Merge tag 'apache-royale-0.9.6'
diff --git a/.gitignore b/.gitignore
index 7c415e6..d777804 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,10 @@
 *.iws
 *.eml
 
+# VSCode conf files
+**/.vscode/**
+*.code-workspace
+
 #OS junk files
 [Tt]humbs.db
 *.DS_Store
@@ -42,4 +46,7 @@
 debugger/generated/
 
 # Asciidoctor related temp files
-ditaa-diagram.*
\ No newline at end of file
+ditaa-diagram.*
+
+# JUnit temp files
+junittestcases*.properties
\ No newline at end of file
diff --git a/ApproveFalcon.xml b/ApproveFalcon.xml
index 9c1e3fc..ba95ad6 100644
--- a/ApproveFalcon.xml
+++ b/ApproveFalcon.xml
@@ -56,8 +56,8 @@
     <property name="bin.rat.report" value="${basedir}/rat-report-bin.txt"/>
     <property name="apache.rat.jar" value="apache-rat-0.11.jar" />
     <property name="apache.rat.tasks.jar" value="apache-rat-tasks-0.11.jar" />
-    <property name="apache.rat.url" value="http://search.maven.org/remotecontent?filepath=org/apache/rat/apache-rat/0.11" />
-    <property name="apache.rat.tasks.url" value="http://search.maven.org/remotecontent?filepath=org/apache/rat/apache-rat-tasks/0.11" />
+    <property name="apache.rat.url" value="https://search.maven.org/remotecontent?filepath=org/apache/rat/apache-rat/0.11" />
+    <property name="apache.rat.tasks.url" value="https://search.maven.org/remotecontent?filepath=org/apache/rat/apache-rat-tasks/0.11" />
 	   
     <property file="${basedir}/approveroyale.properties"/>
     
diff --git a/Jenkinsfile b/Jenkinsfile
index d5d533a..3490bb5 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -23,7 +23,7 @@
 
 // Run only on the windows-2012-1 agent as this is the only one setup to fully
 // support Royale builds.
-node('windows-2012-1') {
+node('jenkins-win-he-de-1') {
 
     currentBuild.result = "SUCCESS"
 
diff --git a/LICENSE b/LICENSE
index d645695..77de039 100644
--- a/LICENSE
+++ b/LICENSE
@@ -200,3 +200,21 @@
    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.
+
+--------------------------------------------------------------------------------
+
+APACHE ROYALE SUBCOMPONENTS:
+
+The Apache Royale SDK includes a number of subcomponents with
+separate copyright notices and license terms. Your use of the source
+code for the these subcomponents is subject to the terms and
+conditions of the following licenses. Paths are relative to the royale-compiler
+folder.
+
+The following .java files in 
+compiler-jx/src/main/java/com/google/javascript/jscomp
+are derived from the files in the Google Closure Compiler which are available 
+under Apache License 2.0.
+
+RoyaleClosurePassConfig.java
+Files with names ending with WithModuleSupport.java
diff --git a/NOTICE b/NOTICE
index ee01330..6f9f984 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,13 +1,16 @@
 Apache Royale Compiler
-Copyright 2018 The Apache Software Foundation
+Copyright 2019 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
 
 The Initial Developer of the Original Code, known as Adobe Flex
-and Adobe ASC 2.0, is Adobe Systems Incorporated (http://www.adobe.com/).
+and Adobe ASC 2.0 and JBurgGenerator.java, is Adobe Systems Incorporated 
+(http://www.adobe.com/).
     Copyright 2003 - 2012 Adobe Systems Incorporated. All Rights Reserved.
 
 The flex-compiler-oem compiler contains code written by Jeff Dyer at: 
     Copyright Mountain View Compiler Company (1998-2003).
 
+Portions of JBurgGenerator.java contains code written by Tom Harwood
+    Copyright Tom Harwood (2003-2008).
diff --git a/NOTICE.base b/NOTICE.base
index 1a99147..69caa49 100644
--- a/NOTICE.base
+++ b/NOTICE.base
@@ -1,5 +1,5 @@
 Apache Royale Compiler
-Copyright 2018 The Apache Software Foundation
+Copyright 2019 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
diff --git a/NOTICE.fdb b/NOTICE.fdb
index e8dea8a..fd988a9 100644
--- a/NOTICE.fdb
+++ b/NOTICE.fdb
@@ -1,5 +1,5 @@
 Apache Royale Debugger
-Copyright 2018 The Apache Software Foundation
+Copyright 2019 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
diff --git a/NOTICE.oem b/NOTICE.oem
index 1dc6435..e5c6bf7 100644
--- a/NOTICE.oem
+++ b/NOTICE.oem
@@ -1,5 +1,5 @@
 Apache Royale Compiler
-Copyright 2018 The Apache Software Foundation
+Copyright 2019 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
diff --git a/README b/README
index 4a807a6..a1376d4 100644
--- a/README
+++ b/README
@@ -268,7 +268,7 @@
         commons-compress - https://repo1.maven.org/maven2/org/apache/commons/commons-compress/1.10/commons-compress-1.10.jar
         guava - https://repo1.maven.org/maven2/com/google/guava/guava/17.0/guava-17.0.jar
         jburg - https://repo1.maven.org/maven2/net/sourceforge/jburg/jburg/1.10.2/jburg-1.10.2.jar
-        jflex - http://jflex.de/jflex-1.6.0.tar.gz
+        jflex - https://jflex.de/jflex-1.6.0.tar.gz
         lzma - http://www.java2s.com/Code/JarDownload/lzma/lzma-9.20.jar.zip
         Google Closure Compiler - http://github.com/google/closure-compiler/archive/v	20151015.zip
 
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 7cd179f..b59e3bb 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -1,3 +1,18 @@
+Apache Royale Compiler 0.9.6
+=================
+
+ - Added -allow-abstract-classes compiler option to enable abstract keyword for classes and methods.
+ - Added -allow-private-constructors compiler option to enable classes with private constructors.
+ - Added -allow-import-aliases compiler option to enable import renaming syntax.
+ - Added -verbose compiler option to reduce console output by default.
+ - Added RoyaleUnit tasks for Apache Ant.
+ - Fix incorrect compiler error when unicodeRange value is specified for Embed metadata.
+ - Fix missing compiler error when adding type parameters to classes other the Vector.
+ - Fix missing compiler error for intantiation of a variable with new that is not typed as Class or Function.
+ - Fix missing compiler warning for missing types on function parameter.
+ - Fix internal cache that broke IDEs that use compiler to provide code intelligence.
+ - Fix automatic type coercion in generated JS so that it better matches SWF behavior.
+
 Apache Royale Compiler 0.9.4
 =================
  
diff --git a/build.properties b/build.properties
index d06260b..cd6baca 100644
--- a/build.properties
+++ b/build.properties
@@ -17,7 +17,11 @@
 ##
 ################################################################################
 
-release.version = 0.9.4
+##used by Ant scripts
+release.version=0.9.6
+##used by release jobs on Jenkins
+releaseversion=0.9.6
+developbranchname=release_practice
 
 generated.by.match=/\\*\\*. \\* Generated by Apache Royale Compiler
 generated.by.comment=/**\n\
diff --git a/build.xml b/build.xml
index aa4a673..ac25291 100644
--- a/build.xml
+++ b/build.xml
@@ -70,7 +70,7 @@
 
     <target name="swf" depends="sdk, javadoc, tests" description="Builds SWF compiler, builds Royale Javadoc, and runs SWF compiler tests."/>
 
-    <target name="main" depends="swf, jx, oem, debugger, anttasks" description="Builds Royale SWF compiler, then Royale JS Transpiler"/>
+    <target name="main" depends="swf, jx, oem, debugger, anttasks, royaleunit.anttasks" description="Builds Royale SWF compiler, then Royale JS Transpiler"/>
 
     <target name="jx" depends="compiler.jx, compiler.jx.tests" description="Builds Royale JS Transpiler" />
     
@@ -92,6 +92,10 @@
         <ant dir="royale-ant-tasks" target="jar"/>
     </target>
 
+    <target name="royaleunit.anttasks" description="Builds RoyaleUnit ant tasks JAR">
+        <ant dir="royaleunit-ant-tasks" target="jar"/>
+    </target>
+
     <target name="debugger" depends="swfutils" description="Builds FDB JAR">
         <ant dir="debugger" target="jar"/>
     </target>
@@ -108,6 +112,10 @@
         <ant dir="royale-ant-tasks" target="test"/>
     </target>
 
+    <target name="royaleunit.ant.tests" description="Runs the tests." unless="skip.compiler.jx.tests">
+        <ant dir="royaleunit-ant-tasks" target="test"/>
+    </target>
+
     <target name="copyLastSuccessfulBuild" description="Copies last royale-asjs build.">
         <ant dir="compiler-jx/src/test" target="copyLastSuccessfulBuild"/>
     </target>
@@ -130,6 +138,7 @@
         <ant dir="flex-compiler-oem" target="clean"/>
         <ant dir="swfutils" target="clean"/>
         <ant dir="royale-ant-tasks" target="clean"/>
+        <ant dir="royaleunit-ant-tasks" target="clean"/>
         <ant dir="debugger" target="clean"/>
     </target>
 
@@ -156,6 +165,7 @@
         <ant dir="flex-compiler-oem" target="wipe"/>
         <ant dir="swfutils" target="wipe"/>
         <ant dir="royale-ant-tasks" target="wipe"/>
+        <ant dir="royaleunit-ant-tasks" target="wipe"/>
         <ant dir="debugger" target="clean"/>
         <delete dir="${basedir}/out" failonerror="false" includeEmptyDirs="true"/>
         <delete dir="${basedir}/temp" failonerror="false" includeEmptyDirs="true"/>
@@ -248,6 +258,7 @@
 
         <copy todir="${staging-dir}" includeEmptyDirs="false">
             <fileset dir="${basedir}">
+                <include name=".mvn/extensions.xml"/>
                 <include name="build.xml"/>
                 <include name="build.properties"/>
                 <include name="env-template.properties"/>
@@ -459,6 +470,19 @@
                 <exclude name="target/META-INF/**"/>
             </fileset>
         </copy>
+        <copy todir="${staging-dir}/royaleunit-ant-tasks" includeEmptyDirs="false">
+            <fileset dir="${basedir}/royaleunit-ant-tasks">
+                <include name="**"/>
+                <exclude name=".classpath" />
+                <exclude name=".project" />
+                <exclude name=".settings/**" />
+                <exclude name="target/classes/**"/>
+                <exclude name="target/flex/**"/>
+                <exclude name="target/flash/**"/>
+                <exclude name="target/generated-sources/**"/>
+                <exclude name="target/META-INF/**"/>
+            </fileset>
+        </copy>
     </target>
 
     <target name="stage-source-jx"
diff --git a/compiler-build-tools/pom.xml b/compiler-build-tools/pom.xml
index 734ab70..235eca6 100644
--- a/compiler-build-tools/pom.xml
+++ b/compiler-build-tools/pom.xml
@@ -29,7 +29,7 @@
 

   <groupId>org.apache.royale.compiler</groupId>

   <artifactId>compiler-build-tools</artifactId>

-  <version>1.0.0</version>

+  <version>1.1.0</version>

   <packaging>maven-plugin</packaging>

 

   <name>Apache Royale: Build Tools</name>

@@ -37,6 +37,11 @@
   <build>

     <plugins>

       <plugin>

+        <groupId>io.github.zlika</groupId>

+        <artifactId>reproducible-build-maven-plugin</artifactId>

+        <version>0.9</version>

+      </plugin>

+      <plugin>

         <groupId>org.apache.maven.plugins</groupId>

         <artifactId>maven-plugin-plugin</artifactId>

         <version>3.5</version>

@@ -68,6 +73,18 @@
     <pluginManagement>

       <plugins>

         <plugin>

+          <groupId>io.github.zlika</groupId>

+          <artifactId>reproducible-build-maven-plugin</artifactId>

+          <version>0.9</version>

+          <executions>

+            <execution>

+              <goals>

+                <goal>strip-jar</goal>

+              </goals>

+            </execution>

+          </executions>

+        </plugin>

+        <plugin>

           <groupId>org.apache.maven.plugins</groupId>

           <artifactId>maven-javadoc-plugin</artifactId>

           <version>2.10.4</version>

@@ -127,6 +144,11 @@
 

   <dependencies>

     <dependency>

+      <groupId>com.google.guava</groupId>

+      <artifactId>guava</artifactId>

+      <version>25.1-jre</version>

+    </dependency>

+    <dependency>

       <groupId>org.apache.maven</groupId>

       <artifactId>maven-core</artifactId>

       <version>3.5.4</version>

diff --git a/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/annotate/AnnotateClass.java b/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/annotate/AnnotateClass.java
index 9d0e9e5..a80b33b 100644
--- a/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/annotate/AnnotateClass.java
+++ b/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/annotate/AnnotateClass.java
@@ -38,11 +38,24 @@
         }
     }
     
-    public static void processFile(File file, String annotation) throws AnnotateClassDeleteException, AnnotateClassRenameException {
+    public static void processFile(File file, String annotation, String dateStart, String dateEnd) throws AnnotateClassDeleteException, AnnotateClassRenameException {
         if(!file.exists()) {
             System.out.println("Missing file: " + file.getPath());
             return;
         }
+        String comment = "";
+        if (dateStart.length() > 0)
+        {
+            int c = dateStart.indexOf("***");
+            if (c > -1)
+            {
+                comment = dateStart.substring(0, c);
+                dateStart = dateStart.substring(c + 3);
+            }
+            System.out.println("searching for generated date line starting with: '" + dateStart + "'");
+            if (comment.length() > 0)
+                System.out.println("and comment starting with: '" + comment + "'");
+        }
         try
         {
             // Prepare to read the file.
@@ -60,6 +73,26 @@
                 boolean alreadyAnnotated = false;
                 while ((line = bufferedReader.readLine()) != null)
                 {
+                    if (dateStart.length() > 0)
+                    {
+                        if ((comment.length() > 0 && line.startsWith(comment)) || comment.length() == 0)
+                        {
+                            int c = line.indexOf(dateStart);
+                            if (c > -1)
+                            {
+                                if (dateEnd.length() > 0)
+                                {
+                                    int c1 = line.lastIndexOf(dateEnd);
+                                    if (c1 > 0)
+                                    {
+                                        line = comment + dateStart + line.substring(c1);
+                                    }
+                                }
+                                else
+                                    line = comment + dateStart;
+                            }
+                        }
+                    }
                     // If the class is already annotated, prevent us from doing it again.
                     if (line.contains(annotation)) {
                         alreadyAnnotated = true;
@@ -91,11 +124,33 @@
                 } catch(Exception e) {
                     // Ignore.
                 }
+                try {
+                    inputStreamReader.close();
+                } catch(Exception e) {
+                    // Ignore.
+                }
+                try {
+                    fileInputStream.close();
+                } catch(Exception e) {
+                    // Ignore.
+                }
             }
 
             // Remove the original file.
             if(!file.delete()) {
-                throw new AnnotateClassDeleteException("Error deleting original file at: " + file.getPath());
+                // wait a bit then retry on Windows
+                if (file.exists())
+                {
+                    for (int i = 0; i < 6; i++)
+                    {
+                        Thread.sleep(500);
+                        System.gc();
+                        if (file.delete())
+                           break;
+                    }
+                    if (file.exists())
+                        throw new AnnotateClassDeleteException("Error deleting original file at: " + file.getPath());
+                }
             }
 
             // Rename the temp file to the name of the original file.
@@ -114,8 +169,10 @@
     {
         File f = new File(args[0]);
         String annotation = args[1];
+        String dateStart = args[2];
+        String dateEnd = args[3];
         try {
-            processFile(f, annotation);
+            processFile(f, annotation, dateStart, dateEnd);
         } catch (Exception e) {
             e.printStackTrace();
         }
diff --git a/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/annotate/AnnotateClassesMojo.java b/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/annotate/AnnotateClassesMojo.java
index 3999688..92223ca 100644
--- a/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/annotate/AnnotateClassesMojo.java
+++ b/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/annotate/AnnotateClassesMojo.java
@@ -47,6 +47,12 @@
     @Parameter(property="annotation", required=true)
     private String annotation;
 
+    @Parameter(property="dateStart", required=false)
+    private String dateStart = "";
+    
+    @Parameter(property="dateEnd", required=false)
+    private String dateEnd = "";
+    
     public void execute()
         throws MojoExecutionException
     {
@@ -58,7 +64,7 @@
             Set<File> candidates = scan.getIncludedSources(directory, null);
             for(File candidate : candidates) {
                 try {
-                    AnnotateClass.processFile(candidate, annotation);
+                    AnnotateClass.processFile(candidate, annotation, dateStart, dateEnd);
                 } catch(AnnotateClass.AnnotateClassDeleteException e) {
                     throw new MojoExecutionException(e.getMessage());
                 } catch(AnnotateClass.AnnotateClassRenameException e) {
diff --git a/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/problems/BaseProblemGeneratorMojo.java b/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/problems/BaseProblemGeneratorMojo.java
index 3af7b1c..6aa695e 100644
--- a/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/problems/BaseProblemGeneratorMojo.java
+++ b/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/problems/BaseProblemGeneratorMojo.java
@@ -113,6 +113,11 @@
                     {
                         return isProblemClass(input);
                     }
+                    @Override
+                    public boolean test(File input)
+                    {
+                        return apply(input);
+                    }
                 });
     }
 
diff --git a/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/problems/ProblemResourceBundleGeneratorMojo.java b/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/problems/ProblemResourceBundleGeneratorMojo.java
index b8a3193..0183982 100644
--- a/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/problems/ProblemResourceBundleGeneratorMojo.java
+++ b/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/problems/ProblemResourceBundleGeneratorMojo.java
@@ -61,7 +61,9 @@
 
     @Override
     protected void printEntry(PrintWriter writer, File source, boolean last) {
-        writer.println(getProblemName(source) + "=" + getProblemDescription(source));
+        // don't use println otherwise file has windows line-endings on windows and
+        // won't compare to osx version
+        writer.print(getProblemName(source) + "=" + getProblemDescription(source) + "\n");
     }
 
     private String getProblemName(File sourceFile) {
diff --git a/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/unknowntreehandler/UnknownTreePatternInputOutput.java b/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/unknowntreehandler/UnknownTreePatternInputOutput.java
index 2ad0d36..955e820 100644
--- a/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/unknowntreehandler/UnknownTreePatternInputOutput.java
+++ b/compiler-build-tools/src/main/java/org/apache/royale/compiler/tools/unknowntreehandler/UnknownTreePatternInputOutput.java
@@ -230,7 +230,10 @@
         output.println("public class " + this.className);
         output.println("{");
         output.println();
-        output.println("    //  Patterns generated " + new java.util.Date().toString() + " from " + src_file_name.replaceAll("\\\\", "/"));
+        String src = src_file_name.replaceAll("\\\\", "/");
+        int c = src.indexOf("compiler/src");
+        src = src.substring(c);
+        output.println("    //  Patterns generated from " + src);
         output.println("    public static Map<ASTNodeID, ArrayList<UnknownTreeFinding.Template> > allTemplates = new HashMap<ASTNodeID, ArrayList<UnknownTreeFinding.Template>>();");
 
         output.println("    static");
diff --git a/compiler-common/pom.xml b/compiler-common/pom.xml
index 2370a7b..581b97d 100644
--- a/compiler-common/pom.xml
+++ b/compiler-common/pom.xml
@@ -1,73 +1,83 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.royale.compiler</groupId>
-        <artifactId>royale-compiler-parent</artifactId>
-        <version>0.9.4</version>
-    </parent>
-
-    <artifactId>compiler-common</artifactId>
-    <version>0.9.4</version>
-
-    <name>Apache Royale: Compiler: Compiler-Common</name>
-    <description>The Apache Royale Compiler Common classes</description>
-  
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.flex</groupId>
-      <artifactId>flex-tool-api</artifactId>
-      <version>1.0.0</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-      <version>2.6</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-cli</groupId>
-      <artifactId>commons-cli</artifactId>
-      <version>1.4</version>
-    </dependency>
-    <dependency>
-      <groupId>org.antlr</groupId>
-      <artifactId>antlr</artifactId>
-      <version>3.3</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-      <version>20.0</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven.plugins</groupId>
-      <artifactId>maven-scm-plugin</artifactId>
-      <version>1.10.0</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven.plugins</groupId>
-      <artifactId>maven-resources-plugin</artifactId>
-      <version>3.1.0</version>
-    </dependency>
-  </dependencies>
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+

+  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.

+

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+  <modelVersion>4.0.0</modelVersion>

+

+    <parent>

+        <groupId>org.apache.royale.compiler</groupId>

+        <artifactId>royale-compiler-parent</artifactId>

+        <version>0.9.6</version>

+    </parent>

+

+    <artifactId>compiler-common</artifactId>

+    <version>0.9.6</version>

+

+    <name>Apache Royale: Compiler: Compiler-Common</name>

+    <description>The Apache Royale Compiler Common classes</description>

+  

+  <build>

+      <plugins>

+          <plugin>

+              <groupId>io.github.zlika</groupId>

+              <artifactId>reproducible-build-maven-plugin</artifactId>

+              <version>0.9</version>

+          </plugin>

+      </plugins>

+  </build>

+  

+  <dependencies>

+    <dependency>

+      <groupId>org.apache.flex</groupId>

+      <artifactId>flex-tool-api</artifactId>

+      <version>1.0.0</version>

+    </dependency>

+    <dependency>

+      <groupId>commons-io</groupId>

+      <artifactId>commons-io</artifactId>

+      <version>2.6</version>

+    </dependency>

+    <dependency>

+      <groupId>commons-cli</groupId>

+      <artifactId>commons-cli</artifactId>

+      <version>1.4</version>

+    </dependency>

+    <dependency>

+      <groupId>org.antlr</groupId>

+      <artifactId>antlr</artifactId>

+      <version>3.3</version>

+    </dependency>

+    <dependency>

+      <groupId>com.google.guava</groupId>

+      <artifactId>guava</artifactId>

+      <version>25.1-jre</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.maven.plugins</groupId>

+      <artifactId>maven-scm-plugin</artifactId>

+      <version>1.10.0</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.maven.plugins</groupId>

+      <artifactId>maven-resources-plugin</artifactId>

+      <version>3.1.0</version>

+    </dependency>

+  </dependencies>

+

+</project>

diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/clients/problems/ProblemSettingsFilter.java b/compiler-common/src/main/java/org/apache/royale/compiler/clients/problems/ProblemSettingsFilter.java
index 8f857c6..2930c7f 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/clients/problems/ProblemSettingsFilter.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/clients/problems/ProblemSettingsFilter.java
@@ -41,6 +41,7 @@
 import org.apache.royale.compiler.problems.ScopedToDefaultNamespaceProblem;
 import org.apache.royale.compiler.problems.SemanticWarningProblem;
 import org.apache.royale.compiler.problems.StrictSemanticsProblem;
+import org.apache.royale.compiler.problems.ThisUsedInClosureProblem;
 import org.apache.royale.compiler.problems.VariableHasNoTypeDeclarationProblem;
 
 /**
@@ -65,6 +66,7 @@
  * -warn-instanceof-changes
  * -warn-missing-namespace-decl
  * -warn-no-type-decl
+ * -warn-this-within-closure
  * 
  */
 public class ProblemSettingsFilter implements IProblemFilter
@@ -186,6 +188,8 @@
                 ICompilerSettings.WARN_MISSING_NAMESPACE_DECL);
         setShowActionScriptWarning(VariableHasNoTypeDeclarationProblem.class, 
                 ICompilerSettings.WARN_NO_TYPE_DECL);
+        setShowActionScriptWarning(ThisUsedInClosureProblem.class, 
+                ICompilerSettings.WARN_THIS_WITHIN_CLOSURE);
     }
 
     /**
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/common/ASModifier.java b/compiler-common/src/main/java/org/apache/royale/compiler/common/ASModifier.java
index bb686ea..a601f80 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/common/ASModifier.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/common/ASModifier.java
@@ -60,6 +60,11 @@
      * Represents the <code>virtual</code> modifier.
 	 */
 	public static final ASModifier VIRTUAL = new ASModifier(IASKeywordConstants.VIRTUAL, 1 << 6);
+
+	/**
+     * Represents the <code>abstract</code> modifier.
+	 */
+	public static final ASModifier ABSTRACT = new ASModifier(IASKeywordConstants.ABSTRACT, 1 << 7);
 	
 	/**
 	 * A list of all the modifiers that exist within AS3
@@ -71,7 +76,8 @@
 		NATIVE,
 		OVERRIDE,
 		STATIC,
-		VIRTUAL
+		VIRTUAL,
+		ABSTRACT
 	};
 	
     /**
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/config/CompilerDiagnosticsConstants.java b/compiler-common/src/main/java/org/apache/royale/compiler/config/CompilerDiagnosticsConstants.java
index 9b6ce58..76eb483 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/config/CompilerDiagnosticsConstants.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/config/CompilerDiagnosticsConstants.java
@@ -40,5 +40,6 @@
     public static final int FILE_UTILS = 4096;
     public static final int ROYALEJSPROJECT = 8192;
     public static final int COMPC_PHASES = 16384;
+    public static final int GOOG_DEPS = 32768;
 
 }
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/config/Configuration.java b/compiler-common/src/main/java/org/apache/royale/compiler/config/Configuration.java
index 85f779f..3817b3e 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/config/Configuration.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/config/Configuration.java
@@ -1485,6 +1485,73 @@
     }
 
     //
+    // 'compiler.allow-import-aliases' option
+    //
+
+    private boolean allowImportAliases = false;
+
+    public boolean getCompilerAllowImportAliases()
+    {
+        return allowImportAliases;
+    }
+
+    /**
+     * Whether the compiler will allow imports to include an optional alias for
+     * the definition name.
+     */
+    @Config
+    @Mapping({ "compiler", "allow-import-aliases" })
+    @RoyaleOnly
+    public void setCompilerAllowImportAliases(ConfigurationValue cv, boolean allow)
+    {
+        this.allowImportAliases = allow;
+    }
+
+    //
+    // 'compiler.allow-abstract-classes' option
+    //
+
+    private boolean allowAbstractClasses = false;
+
+    public boolean getCompilerAllowAbstractClasses()
+    {
+        return allowAbstractClasses;
+    }
+
+    /**
+     * Whether the compiler will allow classes to be abstract.
+     */
+    @Config
+    @Mapping({ "compiler", "allow-abstract-classes" })
+    @RoyaleOnly
+    public void setCompilerAllowAbstractClasses(ConfigurationValue cv, boolean allow)
+    {
+        this.allowAbstractClasses = allow;
+    }
+
+    //
+    // 'compiler.allow-private-constructors' option
+    //
+
+    private boolean allowPrivateConstructors = false;
+
+    public boolean getCompilerAllowPrivateConstructors()
+    {
+        return allowPrivateConstructors;
+    }
+
+    /**
+     * Whether the compiler will allow constructors to be private.
+     */
+    @Config
+    @Mapping({ "compiler", "allow-private-constructors" })
+    @RoyaleOnly
+    public void setCompilerAllowPrivateConstructors(ConfigurationValue cv, boolean allow)
+    {
+        this.allowPrivateConstructors = allow;
+    }
+
+    //
     // 'compiler.actionscript-file-encoding' option
     //
 
@@ -3241,11 +3308,11 @@
     public boolean debug()
     {
         // the debug() in as3 and mxml configuration maps to stacktraceLineNumbers
-        return verboseStacktraces;
+        return generateDebugTags;
     }
 
     public boolean release() {
-        return !verboseStacktraces;
+        return !generateDebugTags;
     }
 
     @Config
@@ -3986,6 +4053,24 @@
     }
 
     //
+    // 'compiler.warn-this-within-closure' option
+    //
+
+    private boolean warn_this_within_closure = true;
+
+    public boolean warn_this_within_closure()
+    {
+        return warn_this_within_closure;
+    }
+
+    @Config(advanced = true)
+    @Mapping({ "compiler", "warn-this-within-closure" })
+    public void setCompilerWarnThisWithinClosure(ConfigurationValue cv, boolean b)
+    {
+        warn_this_within_closure = b;
+    }
+
+    //
     // compiler.generate-abstract-syntax-tree
     //
 
@@ -4569,6 +4654,11 @@
     //
 
     public String date = null;
+    
+    public String getMetadataDate()
+    {
+    	return date;
+    }
 
     @Config
     @Mapping({ "metadata", "date" })
@@ -4579,6 +4669,25 @@
     }
 
     //
+    // 'metadata.dateFormat' option
+    //
+
+    public String dateFormat = null;
+    
+    public String getMetadataDateFormat()
+    {
+    	return dateFormat;
+    }
+
+    @Config
+    @Mapping({ "metadata", "dateFormat" })
+    @Arguments("text")
+    public void setMetadataDateFormat(ConfigurationValue cv, String text)
+    {
+        dateFormat = text;
+    }
+
+    //
     // 'metadata.description' option
     //
 
@@ -5503,6 +5612,24 @@
     }
 
     //
+    // 'swf-debugfile-alias' option
+    //
+
+    private String swfDebugfileAlias;
+
+    public String getSwfDebugfileAlias()
+    {
+        return swfDebugfileAlias;
+    }
+
+    @Config
+    @Arguments("filename")
+    public void setSwfDebugfileAlias(ConfigurationValue val, String output) throws ConfigurationException
+    {
+        this.swfDebugfileAlias = output;
+    }
+
+    //
     // 'dump-config-file' option from ToolsConfiguration
     //
 
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/config/Configurator.java b/compiler-common/src/main/java/org/apache/royale/compiler/config/Configurator.java
index 065f7b1..bb90ae6 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/config/Configurator.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/config/Configurator.java
@@ -2300,6 +2300,7 @@
      * --compiler.warn-slow-text-field-addition
      * --compiler.warn-unlikely-function-value
      * --compiler.warn-xml-class-has-changed
+     * --compiler.warn-this-within-closure
      * </pre>
      * 
      * @param warningCode warning code
@@ -2340,6 +2341,7 @@
      * @see #WARN_SLOW_TEXTFIELD_ADDITION
      * @see #WARN_UNLIKELY_FUNCTION_VALUE
      * @see #WARN_XML_CLASS_HAS_CHANGED
+     * @see #WARN_THIS_WITHIN_CLOSURE
      */
     @Override
     public void checkActionScriptWarning(int warningCode, boolean b)
@@ -2456,6 +2458,9 @@
         case WARN_XML_CLASS_HAS_CHANGED:
             key = COMPILER_WARN_XML_CLASS_HAS_CHANGED;
             break;
+        case WARN_THIS_WITHIN_CLOSURE:
+            key = COMPILER_WARN_THIS_WITHIN_CLOSURE;
+            break;
         }
         
         if (key != null)
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/config/ICompilerProblemSettings.java b/compiler-common/src/main/java/org/apache/royale/compiler/config/ICompilerProblemSettings.java
index 355987e..9e0ed7c 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/config/ICompilerProblemSettings.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/config/ICompilerProblemSettings.java
@@ -157,6 +157,7 @@
       * --compiler.warn-slow-text-field-addition
       * --compiler.warn-unlikely-function-value
       * --compiler.warn-xml-class-has-changed
+      * --compiler.warn-this-within-closure
       * </pre>
       * 
       * @param warningCode warning code, one of:
@@ -198,6 +199,7 @@
       * <li> WARN_SLOW_TEXTFIELD_ADDITION
       * <li> WARN_UNLIKELY_FUNCTION_VALUE
       * <li> WARN_XML_CLASS_HAS_CHANGED
+      * <li> WARN_THIS_WITHIN_CLOSURE
       * </ul>
       * </p>
       */
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/config/ICompilerSettingsConstants.java b/compiler-common/src/main/java/org/apache/royale/compiler/config/ICompilerSettingsConstants.java
index 71a39ec..3dd99ce 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/config/ICompilerSettingsConstants.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/config/ICompilerSettingsConstants.java
@@ -51,6 +51,7 @@
     static final String DEFAULT_BACKGROUND_COLOR                             = "--default-background-color";
     static final String DEBUG_PASSWORD                                       = "--debug-password";
     static final String SWF_VERSION                                          = "--swf-version";
+    static final String COMPILER_WARN_THIS_WITHIN_CLOSURE                    = "--compiler.warn-this-within-closure";
     static final String COMPILER_WARN_XML_CLASS_HAS_CHANGED                  = "--compiler.warn-xml-class-has-changed";
     static final String COMPILER_WARN_UNLIKELY_FUNCTION_VALUE                = "--compiler.warn-unlikely-function-value";
     static final String COMPILER_WARN_SLOW_TEXT_FIELD_ADDITION               = "--compiler.warn-slow-text-field-addition";
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/constants/IASKeywordConstants.java b/compiler-common/src/main/java/org/apache/royale/compiler/constants/IASKeywordConstants.java
index b45cea2..54e17ac 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/constants/IASKeywordConstants.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/constants/IASKeywordConstants.java
@@ -26,6 +26,7 @@
  */
 public interface IASKeywordConstants
 {
+    static final String ABSTRACT = "abstract";
     static final String AS = "as";
     static final String BREAK = "break";
     static final String CASE = "case";
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/constants/IASWarningConstants.java b/compiler-common/src/main/java/org/apache/royale/compiler/constants/IASWarningConstants.java
index 99db8ef..2b6b337 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/constants/IASWarningConstants.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/constants/IASWarningConstants.java
@@ -209,4 +209,9 @@
      * Possible usage of the ActionScript 2.0 <code>XML</code> class.
      */
     static final int XML_CLASS_HAS_CHANGED = 3573;
+
+    /**
+     * Keyword this within closure.
+     */
+    static final int THIS_WITHIN_CLOSURE = 20000;
 }
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/definitions/IDefinition.java b/compiler-common/src/main/java/org/apache/royale/compiler/definitions/IDefinition.java
index 21f225b..89bfd78 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/definitions/IDefinition.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/definitions/IDefinition.java
@@ -268,6 +268,13 @@
     boolean isStatic();
 
     /**
+     * Is this definition marked as <code>abstract</code>?
+     * 
+     * @return <code>true</code> if the definition is <code>abstract</code>.
+     */
+    boolean isAbstract();
+
+    /**
      * Determines whether the specified modifier is present on this definition.
      * See {@link ASModifier} for the list of modifiers.
      * 
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/embedding/EmbedAttribute.java b/compiler-common/src/main/java/org/apache/royale/compiler/embedding/EmbedAttribute.java
index a1563fa..87f623e 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/embedding/EmbedAttribute.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/embedding/EmbedAttribute.java
@@ -44,6 +44,7 @@
     // report one problem that font embeddeding is not supported.
     ADV_ANTI_ALIASING("advancedAntiAliasing"),
     EMBED_AS_CFF("embedAsCFF"),
+    UNICODE_RANGE("unicodeRange"),
     FONT_FAMILY("fontFamily"),
     FONT_NAME("fontName"),
     FONT_STYLE("fontStyle"),
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/filespecs/CombinedFile.java b/compiler-common/src/main/java/org/apache/royale/compiler/filespecs/CombinedFile.java
index bcf48b5..6025ae6 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/filespecs/CombinedFile.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/filespecs/CombinedFile.java
@@ -242,4 +242,10 @@
         // No BOM tag.
         return BOM.NONE;
     }
+
+	@Override
+	public void setLastModified(long fileDate) {
+		// TODO Auto-generated method stub
+		
+	}
 }
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/filespecs/FileSpecification.java b/compiler-common/src/main/java/org/apache/royale/compiler/filespecs/FileSpecification.java
index 67e1fc8..91dd053 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/filespecs/FileSpecification.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/filespecs/FileSpecification.java
@@ -26,6 +26,7 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.FilterInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -47,6 +48,8 @@
 		super(path);
 	}
 
+	public static boolean useCRLFFilter = false;
+	
 	@Override
 	public int hashCode() {
 		final int prime = 31;
@@ -116,9 +119,12 @@
         final BufferedInputStream strm = new BufferedInputStream(new FileInputStream(file));
 	    final BOM bom = getBOM(strm);
         strm.skip(bom.pattern.length);
-
-        final Reader reader = new BufferedReader(
-                new InputStreamReader(strm, bom.charset));
+        
+        final InputStreamReader inputSR = useCRLFFilter ? 
+        		new InputStreamReader(new NoCRLFInputStream(strm), bom.charset) :
+                new InputStreamReader(strm, bom.charset);
+        			
+        final Reader reader = new BufferedReader(inputSR);
         return reader;
 	}
 
@@ -127,4 +133,106 @@
     {
         return new BufferedInputStream(new FileInputStream(getFileHandle()));
     }
+
+	@Override
+	public void setLastModified(long fileDate) {
+		File fileHandle = getFileHandle();
+		fileHandle.setLastModified(fileDate);
+	}
+	
+	public static class NoCRLFInputStream extends FilterInputStream
+	{
+		public NoCRLFInputStream(InputStream fileInputStream)
+		{
+			super(fileInputStream);
+		}
+		
+		/**
+		 * if we read a CR, just skip it, assuming it will
+		 * be followed by an LF
+		 */
+		@Override
+		public int read() throws IOException
+		{
+			int retval = super.read();
+			if (retval == '\r')
+				retval = super.read();
+			return retval;
+		}
+		
+		/**
+		 * if we read a CR, just skip it, assuming it will
+		 * be followed by an LF
+		 * @throws IOException 
+		 */
+		@Override
+		public int read(byte[] b) throws IOException
+		{
+			int n = b.length;
+			byte[] temp = new byte[b.length];
+			int retval = super.read(temp);
+			if (retval == -1)
+				return -1;
+			
+			int j = 0;
+			for (int i = 0; i < retval; i++)
+			{
+				byte c = temp[i];
+				if (c == '\r')
+					continue;
+				else
+					b[j++] = c;
+			}
+			while (j < retval)
+			{
+				int extra = super.read(b, j, 1);
+				if (extra == -1)
+					break;
+				byte c = b[j];
+				if (c == '\r')
+					continue;
+				else
+				    j++;
+			}
+			return j;
+		}
+
+		/**
+		 * if we read a CR, just skip it, assuming it will
+		 * be followed by an LF
+		 * @throws IOException 
+		 */
+		@Override
+		public int read(byte[] b, int off, int len) throws IOException
+		{
+			byte[] temp = new byte[len];
+			int retval = super.read(temp, off, len);
+			if (retval == -1)
+				return -1;
+			if (retval == 0)
+				return 0;
+			
+			int j = 0;
+			for (int i = off; i < retval; i++)
+			{
+				byte c = temp[i];
+				if (c == '\r')
+					continue;
+				else
+					b[off + j++] = c;
+			}
+//			System.out.println(new String(b));
+			while (j < retval)
+			{
+				int extra = super.read(b, off + j, 1);
+				if (extra == -1)
+					break;
+				byte c = b[off + j];
+				if (c == '\r')
+					continue;
+				j++;
+			}
+			return j;
+		}
+	}
 }
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/filespecs/IFileSpecification.java b/compiler-common/src/main/java/org/apache/royale/compiler/filespecs/IFileSpecification.java
index bb40f3e..246ff8d 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/filespecs/IFileSpecification.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/filespecs/IFileSpecification.java
@@ -49,6 +49,13 @@
 	 */
 	long getLastModified();
 	
+
+	/**
+	 * Set the last modified timestamp of the file
+	 * @param fileDate	the last modified timestamp
+	 */
+	void setLastModified(long fileDate);
+	
     /**
      * @return true if this file specification refers to an open document and
      * the {@link #createReader()} method returns a reader that reads the live
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/internal/config/CompilerProblemSettings.java b/compiler-common/src/main/java/org/apache/royale/compiler/internal/config/CompilerProblemSettings.java
index 868293f..3bdc442 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/internal/config/CompilerProblemSettings.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/internal/config/CompilerProblemSettings.java
@@ -213,6 +213,9 @@
         case ICompilerSettings.WARN_XML_CLASS_HAS_CHANGED:
             warning = configuration.warn_xml_class_has_changed();
             break;
+        case ICompilerSettings.WARN_THIS_WITHIN_CLOSURE:
+            warning = configuration.warn_this_within_closure();
+            break;
         }
         
         return warning;
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/internal/config/ICompilerSettings.java b/compiler-common/src/main/java/org/apache/royale/compiler/internal/config/ICompilerSettings.java
index 4bc7e75..054de47 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/internal/config/ICompilerSettings.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/internal/config/ICompilerSettings.java
@@ -547,6 +547,11 @@
      * Possible usage of the ActionScript 2.0 <code>XML</code> class.
      */
     int WARN_XML_CLASS_HAS_CHANGED = IASWarningConstants.XML_CLASS_HAS_CHANGED;
+
+    /**
+     * Keyword this within closure.
+     */
+    int WARN_THIS_WITHIN_CLOSURE = IASWarningConstants.THIS_WITHIN_CLOSURE;
      
     /**
      * Enables checking of the following ActionScript warnings:
@@ -588,6 +593,7 @@
      * --compiler.warn-slow-text-field-addition
      * --compiler.warn-unlikely-function-value
      * --compiler.warn-xml-class-has-changed
+     * --compiler.warn-this-within-closure
      * </pre>
      * 
      * @param warningCode Warning code.
@@ -629,6 +635,7 @@
      * @see #WARN_SLOW_TEXTFIELD_ADDITION
      * @see #WARN_UNLIKELY_FUNCTION_VALUE
      * @see #WARN_XML_CLASS_HAS_CHANGED
+     * @see #WARN_THIS_WITHIN_CLOSURE
      */
     void checkActionScriptWarning(int warningCode, boolean b);
 
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/internal/config/TargetSettings.java b/compiler-common/src/main/java/org/apache/royale/compiler/internal/config/TargetSettings.java
index bc2ab9f..919b4fb 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/internal/config/TargetSettings.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/internal/config/TargetSettings.java
@@ -594,4 +594,15 @@
     {
         return configuration.getRemoveDeadCode();
     }
+
+	@Override
+	public String getSWFMetadataDate() {
+		return configuration.getMetadataDate();
+	}
+	
+	@Override
+	public String getSWFMetadataDateFormat() {
+		return configuration.getMetadataDateFormat();
+	}
+
 }
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/internal/parsing/as/OffsetLookup.java b/compiler-common/src/main/java/org/apache/royale/compiler/internal/parsing/as/OffsetLookup.java
index 376fb47..26b7699 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/internal/parsing/as/OffsetLookup.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/internal/parsing/as/OffsetLookup.java
@@ -88,7 +88,8 @@
      * @param absoluteOffset absolute offset
      * @return The {@code OffsetCue} that applies to the given absolute offset.
      */
-    private OffsetCue findOffsetCue(int absoluteOffset)
+    @SuppressWarnings("deprecation")
+	private OffsetCue findOffsetCue(int absoluteOffset)
     {
         if (offsetCueList.isEmpty() || absoluteOffset < 0)
             return null;
@@ -169,6 +170,12 @@
                     {
                         return cue.filename.equals(filename);
                     }
+                    
+                    @Override
+                    public boolean test(OffsetCue input)
+                    {
+                        return apply(input);
+                    }
                 });
 
         // Find a list of OffsetCues before the local offset.
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/problems/FilePrivateItemsWithMainVarWarningProblem.java b/compiler-common/src/main/java/org/apache/royale/compiler/problems/FilePrivateItemsWithMainVarWarningProblem.java
new file mode 100644
index 0000000..10e8db7
--- /dev/null
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/problems/FilePrivateItemsWithMainVarWarningProblem.java
@@ -0,0 +1,50 @@
+/*
+ *
+ *  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.royale.compiler.problems;
+
+import org.apache.royale.compiler.common.ISourceLocation;
+import org.apache.royale.compiler.problems.annotations.DefaultSeverity;
+
+/**
+ *  When a variable is the externally accessible package scoped definition, there is a
+ *  namespace implementation issue in javascript for other file-private members.
+ *  This use case seems limited, as it is likely that the externally visible variable
+ *  definition would need to depend on the file-private definitions, otherwise it is
+ *  questionable why they would even exist. Given the likelihood that this is very limited,
+ *  it is currently not recommended.
+ */
+@DefaultSeverity(CompilerProblemSeverity.WARNING)
+public class FilePrivateItemsWithMainVarWarningProblem extends CompilerProblem
+{
+    public static final String DESCRIPTION =
+        "Using file-private definitions outside a package level variable is not recommended and may not work (javascript).";
+    
+    public static final int warningCode = 5045;
+    
+    public FilePrivateItemsWithMainVarWarningProblem(ISourceLocation site)
+    {
+        super(site);
+    }
+    
+    public FilePrivateItemsWithMainVarWarningProblem(String sourcePath, int start, int end, int line, int column, int endLine, int endColumn)
+    {
+        super(sourcePath, start, end, line, column, endLine, endColumn);
+    }
+    
+}
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/problems/ParameterHasNoTypeDeclarationProblem.java b/compiler-common/src/main/java/org/apache/royale/compiler/problems/ParameterHasNoTypeDeclarationProblem.java
new file mode 100644
index 0000000..d64d973
--- /dev/null
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/problems/ParameterHasNoTypeDeclarationProblem.java
@@ -0,0 +1,46 @@
+/*
+ *
+ *  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.royale.compiler.problems;
+
+import org.apache.royale.compiler.tree.as.IASNode;
+
+/**
+ * <pre>
+ * Example: 
+ *      function foo(baz) : void {
+ *      }
+ * </pre>
+ *          
+ */
+public final class ParameterHasNoTypeDeclarationProblem extends SemanticWarningProblem
+{
+    public static final String DESCRIPTION = "parameter '${paramName}' for function '${functionName}' has no type declaration.";
+    
+    public static final int warningCode = 1008;
+    public ParameterHasNoTypeDeclarationProblem(IASNode site, String paramName, String functionName)
+    {
+        super(site);
+		this.paramName = paramName;
+		this.functionName = functionName;
+    }
+    
+    public final String paramName;
+    public final String functionName;
+}
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/problems/PublicVarWarningProblem.java b/compiler-common/src/main/java/org/apache/royale/compiler/problems/PublicVarWarningProblem.java
index 02fddc8..6a4ce55 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/problems/PublicVarWarningProblem.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/problems/PublicVarWarningProblem.java
@@ -41,4 +41,10 @@
     {
         super(site);
     }
+    
+    public PublicVarWarningProblem(String sourcePath, int start, int end, int line, int column, int endLine, int endColumn)
+    {
+        super(sourcePath, start, end, line, column, endLine, endColumn);
+    }
+    
 }
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/problems/ThisUsedInClosureProblem.java b/compiler-common/src/main/java/org/apache/royale/compiler/problems/ThisUsedInClosureProblem.java
new file mode 100644
index 0000000..28ef5df
--- /dev/null
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/problems/ThisUsedInClosureProblem.java
@@ -0,0 +1,42 @@
+/*
+ *
+ *  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.royale.compiler.problems;
+
+import org.apache.royale.compiler.tree.as.IASNode;
+
+/**
+ *  Diagnostic emitted when the method body semantic checker detects
+ *  a reference to "this" in a closure
+ */
+public final class ThisUsedInClosureProblem extends SemanticWarningProblem
+{
+    public static final String DESCRIPTION =
+        "Encountered ${THIS} keyword within closure. Value of ${THIS} will not be the same as enclosing scope.";
+    
+    public static final int warningCode = 20000;
+
+    public ThisUsedInClosureProblem(IASNode site)
+    {
+        super(site);
+    }
+
+    // Prevent these from being localized.
+    public final String THIS = "this";
+}
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/projects/ICompilerProject.java b/compiler-common/src/main/java/org/apache/royale/compiler/projects/ICompilerProject.java
index 332576a..00042f9 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/projects/ICompilerProject.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/projects/ICompilerProject.java
@@ -265,6 +265,21 @@
     /**
      * @return True if a subclass can have a private API with the same name as a private API in its base classes.
      */
-	boolean getAllowPrivateNameConflicts();
+     boolean getAllowPrivateNameConflicts();
+     
+    /**
+     * @return True if import aliases are allowed.
+     */
+     boolean getAllowImportAliases();
+     
+     /**
+      * @return True if abstract classes are allowed.
+      */
+     boolean getAllowAbstractClasses();
+     
+     /**
+      * @return True if private constructors are allowed.
+      */
+     boolean getAllowPrivateConstructors();
 
 }
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/targets/ITargetSettings.java b/compiler-common/src/main/java/org/apache/royale/compiler/targets/ITargetSettings.java
index 946e670..f1b6672 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/targets/ITargetSettings.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/targets/ITargetSettings.java
@@ -500,5 +500,19 @@
      * @return An array of strings specifying the import targets.
      */
     String[] getMxmlImplicitImports();
+    
+    /**
+     * Gets Date string used in RDF metadata.
+     * 
+     * @return null or RDF date.
+     */
+    String getSWFMetadataDate();
+    
+    /**
+     * Gets DateFormat string used in RDF metadata date.
+     * 
+     * @return null or Java SimpleDateFormat pattern.
+     */
+    String getSWFMetadataDateFormat();
 }
 
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/tree/as/IFunctionNode.java b/compiler-common/src/main/java/org/apache/royale/compiler/tree/as/IFunctionNode.java
index e85cb07..64755fd 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/tree/as/IFunctionNode.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/tree/as/IFunctionNode.java
@@ -172,16 +172,4 @@
      * JS codegen needs to know about them.
      */
     void rememberLocalFunction(IFunctionNode localFunction);
-    
-    /**
-     * flag to determine whether to emit the local function
-     * or a reference to it
-     */
-    boolean getEmittingLocalFunctions();
-    
-    /**
-     * flag to determine whether to emit the local function
-     * or a reference to it
-     */
-    void setEmittingLocalFunctions(boolean emit);
 }
diff --git a/compiler-externc/.classpath b/compiler-externc/.classpath
index 2274c0b..1c61f77 100644
--- a/compiler-externc/.classpath
+++ b/compiler-externc/.classpath
@@ -1,6 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<classpathentry kind="src" path="src/test/java"/>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
 	<classpathentry kind="src" path="src/main/java"/>
 	<classpathentry kind="lib" path="../compiler/lib/external/commons-cli.jar"/>
 	<classpathentry kind="lib" path="../compiler/lib/external/commons-io.jar"/>
diff --git a/compiler-externc/build.xml b/compiler-externc/build.xml
index 773a0ee..57b349f 100644
--- a/compiler-externc/build.xml
+++ b/compiler-externc/build.xml
@@ -161,6 +161,7 @@
 
     <target name="clean" description="clean">
         <delete dir="${compiler-externc}/target/classes"/>
+        <delete file="${compiler-externc}/target/js.swc"/>
     </target>
 
     <target name="wipe" depends="clean" description="Wipes everything that didn't come from Git.">
diff --git a/compiler-externc/pom.xml b/compiler-externc/pom.xml
index 249ed9d..a9ff8b1 100644
--- a/compiler-externc/pom.xml
+++ b/compiler-externc/pom.xml
@@ -1,153 +1,158 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.apache.royale.compiler</groupId>
-    <artifactId>royale-compiler-parent</artifactId>
-    <version>0.9.4</version>
-  </parent>
-
-  <artifactId>compiler-externc</artifactId>
-  <version>0.9.4</version>
-
-  <name>Apache Royale: Compiler: Externc</name>
-  <description>The Apache Royale Compiler Externs Compiler</description>
-
-  <build>
-    <plugins>
-        <plugin>
-            <groupId>org.apache.royale.compiler</groupId>
-            <artifactId>compiler-build-tools</artifactId>
-            <version>${compiler-build-tools.version}</version>
-            <executions>
-                <execution>
-                    <id>unpack-closure-externs</id>
-                    <phase>validate</phase>
-                    <goals>
-                        <goal>unpack-resources</goal>
-                    </goals>
-                    <configuration>
-                        <resource>externs.zip</resource>
-                    </configuration>
-                </execution>
-            </executions>
-            <!--
-             Dependency to the closure compiler externs artifact so
-             the "unpack-resources" goal can find the externs.zip
-             -->
-            <dependencies>
-                <dependency>
-                    <groupId>com.google.javascript</groupId>
-                    <artifactId>closure-compiler-externs</artifactId>
-                    <version>v20170626</version>
-                </dependency>
-            </dependencies>
-        </plugin>
-        <!-- Make the surefire execute all unit-tests -->
-        <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-surefire-plugin</artifactId>
-            <version>2.19</version>
-            <configuration>
-                <includes>
-                    <include>org/**/TestExternES3.java</include>
-                    <include>org/**/TestExternChrome.java</include>
-                    <include>org/**/TestExternJSMissing.java</include>
-                    <include>org/**/TestAnnotationEnum.java</include>
-                    <include>org/**/TestCollectImports.java</include>
-                    <include>org/**/TestConstructor.java</include>
-                    <include>org/**/TestPackageNamespace.java</include>
-                    <include>org/**/TestReferenceModel.java</include>
-                    <include>org/**/TestTypeTypedefs.java</include>
-                    <include>org/**/TestTypeInheritance.java</include>
-                </includes>
-                <excludes>
-                </excludes>
-            </configuration>
-        </plugin>
-        
-        <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-failsafe-plugin</artifactId>
-            <version>2.18.1</version>
-            <configuration>
-                <includes>
-                    <include>org/**/TestExternES3.java</include>
-                    <include>org/**/TestExternChrome.java</include>
-                    <include>org/**/TestExternJSMissing.java</include>
-                    <include>org/**/TestAnnotationEnum.java</include>
-                    <include>org/**/TestCollectImports.java</include>
-                    <include>org/**/TestConstructor.java</include>
-                    <include>org/**/TestPackageNamespace.java</include>
-                    <include>org/**/TestReferenceModel.java</include>
-                    <include>org/**/TestTypeTypedefs.java</include>
-                    <include>org/**/TestTypeInheritance.java</include>
-                </includes>
-                <excludes>
-                </excludes>
-            </configuration>
-        </plugin>
-        
-        <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-jar-plugin</artifactId>
-            <version>2.2</version>
-            <executions>
-                <execution>
-                    <goals>
-                        <goal>test-jar</goal>
-                    </goals>
-                </execution>
-            </executions>
-        </plugin>
-    </plugins>
-  </build>
-
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>compiler-common</artifactId>
-      <version>0.9.4</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.javascript</groupId>
-      <artifactId>closure-compiler</artifactId>
-      <version>v20170626</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>compiler-test-utils</artifactId>
-      <version>0.9.4</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>4.10</version>
-      <scope>test</scope>
-    </dependency>
-
-  </dependencies>
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+

+  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.

+

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+  <modelVersion>4.0.0</modelVersion>

+

+  <parent>

+    <groupId>org.apache.royale.compiler</groupId>

+    <artifactId>royale-compiler-parent</artifactId>

+    <version>0.9.6</version>

+  </parent>

+

+  <artifactId>compiler-externc</artifactId>

+  <version>0.9.6</version>

+

+  <name>Apache Royale: Compiler: Externc</name>

+  <description>The Apache Royale Compiler Externs Compiler</description>

+

+  <build>

+    <plugins>

+        <plugin>

+            <groupId>io.github.zlika</groupId>

+            <artifactId>reproducible-build-maven-plugin</artifactId>

+            <version>0.9</version>

+        </plugin>

+        <plugin>

+            <groupId>org.apache.royale.compiler</groupId>

+            <artifactId>compiler-build-tools</artifactId>

+            <version>${compiler-build-tools.version}</version>

+            <executions>

+                <execution>

+                    <id>unpack-closure-externs</id>

+                    <phase>validate</phase>

+                    <goals>

+                        <goal>unpack-resources</goal>

+                    </goals>

+                    <configuration>

+                        <resource>externs.zip</resource>

+                    </configuration>

+                </execution>

+            </executions>

+            <!--

+             Dependency to the closure compiler externs artifact so

+             the "unpack-resources" goal can find the externs.zip

+             -->

+            <dependencies>

+                <dependency>

+                    <groupId>com.google.javascript</groupId>

+                    <artifactId>closure-compiler-externs</artifactId>

+                    <version>v20181210</version>

+                </dependency>

+            </dependencies>

+        </plugin>

+        <!-- Make the surefire execute all unit-tests -->

+        <plugin>

+            <groupId>org.apache.maven.plugins</groupId>

+            <artifactId>maven-surefire-plugin</artifactId>

+            <version>2.19</version>

+            <configuration>

+                <includes>

+                    <include>org/**/TestExternES3.java</include>

+                    <include>org/**/TestExternChrome.java</include>

+                    <include>org/**/TestExternJSMissing.java</include>

+                    <include>org/**/TestAnnotationEnum.java</include>

+                    <include>org/**/TestCollectImports.java</include>

+                    <include>org/**/TestConstructor.java</include>

+                    <include>org/**/TestPackageNamespace.java</include>

+                    <include>org/**/TestReferenceModel.java</include>

+                    <include>org/**/TestTypeTypedefs.java</include>

+                    <include>org/**/TestTypeInheritance.java</include>

+                </includes>

+                <excludes>

+                </excludes>

+            </configuration>

+        </plugin>

+        

+        <plugin>

+            <groupId>org.apache.maven.plugins</groupId>

+            <artifactId>maven-failsafe-plugin</artifactId>

+            <version>2.18.1</version>

+            <configuration>

+                <includes>

+                    <include>org/**/TestExternES3.java</include>

+                    <include>org/**/TestExternChrome.java</include>

+                    <include>org/**/TestExternJSMissing.java</include>

+                    <include>org/**/TestAnnotationEnum.java</include>

+                    <include>org/**/TestCollectImports.java</include>

+                    <include>org/**/TestConstructor.java</include>

+                    <include>org/**/TestPackageNamespace.java</include>

+                    <include>org/**/TestReferenceModel.java</include>

+                    <include>org/**/TestTypeTypedefs.java</include>

+                    <include>org/**/TestTypeInheritance.java</include>

+                </includes>

+                <excludes>

+                </excludes>

+            </configuration>

+        </plugin>

+        

+        <plugin>

+            <groupId>org.apache.maven.plugins</groupId>

+            <artifactId>maven-jar-plugin</artifactId>

+            <version>2.2</version>

+            <executions>

+                <execution>

+                    <goals>

+                        <goal>test-jar</goal>

+                    </goals>

+                </execution>

+            </executions>

+        </plugin>

+    </plugins>

+  </build>

+

+

+  <dependencies>

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>compiler-common</artifactId>

+      <version>0.9.6</version>

+    </dependency>

+    <dependency>

+      <groupId>com.google.javascript</groupId>

+      <artifactId>closure-compiler</artifactId>

+      <version>v20181210</version>

+    </dependency>

+

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>compiler-test-utils</artifactId>

+      <version>0.9.6</version>

+      <scope>test</scope>

+    </dependency>

+    <dependency>

+      <groupId>junit</groupId>

+      <artifactId>junit</artifactId>

+      <version>4.10</version>

+      <scope>test</scope>

+    </dependency>

+

+  </dependencies>

+

+</project>

diff --git a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/pass/AbstractCompilerPass.java b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/pass/AbstractCompilerPass.java
index 6d5387a..ed0c68e 100644
--- a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/pass/AbstractCompilerPass.java
+++ b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/pass/AbstractCompilerPass.java
@@ -52,7 +52,7 @@
     public void process(Node externs, Node root)
     {
         //NodeTraversal.traverse(compiler, root, this);
-        NodeTraversal.traverseRootsEs6(compiler, this, externs, root);
+        NodeTraversal.traverseRoots(compiler, this, externs, root);
     }
 
     protected void log(Node n)
diff --git a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/pass/ReferenceCompiler.java b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/pass/ReferenceCompiler.java
index e58c228..8e217bd 100644
--- a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/pass/ReferenceCompiler.java
+++ b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/pass/ReferenceCompiler.java
@@ -67,7 +67,7 @@
         options.setPrettyPrint(true);
         options.setLineLengthThreshold(80);
         options.setPreferSingleQuotes(true);
-        options.setIdeMode(true);
+        //options.setIdeMode(true);
         options.setParseJsDocDocumentation(Config.JsDocParsing.INCLUDE_DESCRIPTIONS_NO_WHITESPACE);
         options.setExternExports(false);
         options.setExtraAnnotationNames(Arrays.asList(asdocTags));
diff --git a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/BaseReference.java b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/BaseReference.java
index e2204b6..0be229f 100644
--- a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/BaseReference.java
+++ b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/BaseReference.java
@@ -32,6 +32,7 @@
 import com.google.javascript.rhino.JSDocInfo.TypePosition;
 import com.google.javascript.rhino.JSTypeExpression;
 import com.google.javascript.rhino.Node;
+import com.google.javascript.rhino.jstype.JSType.Nullability;
 
 public abstract class BaseReference
 {
@@ -275,7 +276,7 @@
             if (outputJS && parameterType != null)
             {
                 sb.append("{");
-                sb.append(mapBackToJS(getModel().evaluate(parameterType).toAnnotationString(), optional));
+                sb.append(mapBackToJS(getModel().evaluate(parameterType).toAnnotationString(Nullability.EXPLICIT), optional));
                 sb.append("}");
                 sb.append(" ");            	
             }
@@ -292,7 +293,7 @@
             if (!outputJS && parameterType != null)
             {
                 sb.append("[");
-                sb.append(getModel().evaluate(parameterType).toAnnotationString());
+                sb.append(getModel().evaluate(parameterType).toAnnotationString(Nullability.EXPLICIT));
                 sb.append("]");
                 sb.append(" ");
             }
@@ -313,9 +314,9 @@
                 sb.append(" * @returns ");
                 sb.append("{");
                 if (outputJS)
-                    sb.append(mapBackToJS(getModel().evaluate(returnType).toAnnotationString(), false));
+                    sb.append(mapBackToJS(getModel().evaluate(returnType).toAnnotationString(Nullability.EXPLICIT), false));
                 else
-                	sb.append(getModel().evaluate(returnType).toAnnotationString());
+                	sb.append(getModel().evaluate(returnType).toAnnotationString(Nullability.EXPLICIT));
                 sb.append("} ");
                 String description = getComment().getReturnDescription();
                 if (description != null)
diff --git a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/ClassReference.java b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/ClassReference.java
index 7817e7c..d32cde3 100644
--- a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/ClassReference.java
+++ b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/ClassReference.java
@@ -40,6 +40,7 @@
 import com.google.javascript.rhino.Node;
 import com.google.javascript.rhino.jstype.JSType;
 import com.google.javascript.rhino.jstype.ObjectType;
+import com.google.javascript.rhino.jstype.TemplatizedType;
 
 public class ClassReference extends BaseReference
 {
@@ -502,7 +503,7 @@
         ArrayList<ClassReference> result = new ArrayList<ClassReference>();
         for (JSTypeExpression jsTypeExpression : getComment().getImplementedInterfaces())
         {
-            String interfaceName = getModel().evaluate(jsTypeExpression).toAnnotationString();
+            String interfaceName = getModel().evaluate(jsTypeExpression).getDisplayName();
             ClassReference reference = getModel().getClassReference(interfaceName);
             if (reference != null)
                 result.add(reference);
@@ -515,7 +516,7 @@
         ArrayList<ClassReference> result = new ArrayList<ClassReference>();
         for (JSTypeExpression jsTypeExpression : getComment().getExtendedInterfaces())
         {
-            String interfaceName = getModel().evaluate(jsTypeExpression).toAnnotationString();
+            String interfaceName = getModel().evaluate(jsTypeExpression).getDisplayName();
             ClassReference reference = getModel().getClassReference(interfaceName);
             if (reference != null)
                 result.add(reference);
@@ -530,7 +531,11 @@
         for (JSTypeExpression jsTypeExpression : implementedInterfaces)
         {
             JSType jsType = getModel().evaluate(jsTypeExpression);
-            String interfaceName = jsType.toAnnotationString();
+            if (jsType.isTemplatizedType())
+            {
+            	jsType = ((TemplatizedType)jsType).getReferencedType();
+            }
+            String interfaceName = jsType.getDisplayName();
             ClassReference interfaceReference = getModel().getClassReference(interfaceName);
             if (interfaceReference != null)
             	result.add(interfaceReference);
@@ -639,6 +644,11 @@
         {
             // skipping Object.prototype.toString() allows toString(opt_radix) for Number, int and uint
         }
+        else if (getQualifiedName().equals("Object") && functionName.equals("toJSON"))
+        {
+            // skipping Object.prototype.toJSON().  Doesn't seem to be in the spec and excluding
+        	// in the config seems to also block Date.toJSON
+        }
         else
         {
             instanceMethods.put(functionName, method);
@@ -871,7 +881,7 @@
             sb.append("extends ");
             for (JSTypeExpression jsTypeExpression : extendedInterfaces)
             {
-                String value = getModel().evaluate(jsTypeExpression).toAnnotationString();
+                String value = getModel().evaluate(jsTypeExpression).toString();
                 sb.append(value);
                 if (--len > 0)
                     sb.append(", ");
diff --git a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/ConstantReference.java b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/ConstantReference.java
index f4c8351..265a842 100644
--- a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/ConstantReference.java
+++ b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/ConstantReference.java
@@ -74,7 +74,17 @@
         if (getQualifiedName().equals("undefined"))
         {
             sb.append(indent);
-            sb.append("public const undefined:* = 0;\n");
+            sb.append("public const undefined:* = void 0;\n");
+        }
+        else if (getQualifiedName().equals("NaN"))
+        {
+            sb.append(indent);
+            sb.append("public const NaN:Number = 0/0;\n");
+        }
+        else if (getQualifiedName().equals("Infinity"))
+        {
+            sb.append(indent);
+            sb.append("public const Infinity:Number = 1/0;\n");
         }
         else
         {
@@ -91,6 +101,7 @@
         HashMap<String, String> map = new HashMap<String, String>();
         map.put("Number", "0");
         map.put("undefined", "0");
+        map.put("Boolean", "false");
 
         if (map.containsKey(type))
             return map.get(type);
diff --git a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/FieldReference.java b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/FieldReference.java
index 3f95e37..95c35ad 100644
--- a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/FieldReference.java
+++ b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/FieldReference.java
@@ -32,6 +32,7 @@
 import com.google.javascript.rhino.JSTypeExpression;
 import com.google.javascript.rhino.Node;
 import com.google.javascript.rhino.jstype.JSType;
+import com.google.javascript.rhino.jstype.JSType.Nullability;
 
 public class FieldReference extends MemberReference
 {
@@ -79,7 +80,7 @@
         {
             jsType = getModel().evaluate(getComment().getType());
         }
-        return jsType != null ? jsType.toAnnotationString() : "Object";
+        return jsType != null ? jsType.toAnnotationString(Nullability.EXPLICIT) : "Object";
     }
 
     public FieldReference(ReferenceModel model, ClassReference classReference, Node node, String name,
@@ -87,7 +88,6 @@
     {
         super(model, classReference, node, name, comment);
         Collection<Marker> markers = comment.getMarkers();
-        Marker[] markerArray = new Marker[markers.size()];
         for (Marker marker : markers)
         {
         	if (marker.getAnnotation().getItem().equals("const"))
@@ -284,7 +284,7 @@
                 sb.append(indent);
                 sb.append(" * @type ");
                 sb.append("{");
-                sb.append(mapBackToJS(getModel().evaluate(type).toAnnotationString(), false));
+                sb.append(mapBackToJS(getModel().evaluate(type).toAnnotationString(Nullability.EXPLICIT), false));
                 sb.append("} ");
                 sb.append("\n");
         	}
@@ -293,7 +293,7 @@
                 sb.append(indent);
                 sb.append(" * @see JSType - ");
                 sb.append("[");
-                sb.append(getModel().evaluate(type).toAnnotationString());
+                sb.append(getModel().evaluate(type).toAnnotationString(Nullability.EXPLICIT));
                 sb.append("] ");
                 String description = getComment().getReturnDescription();
                 if (description != null)
diff --git a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/FunctionReference.java b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/FunctionReference.java
index 6fd200a..8351dd1 100644
--- a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/FunctionReference.java
+++ b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/FunctionReference.java
@@ -130,7 +130,7 @@
 
         braces = " { " + returns + " }";
 
-        sb.append("    ");
+        sb.append(indent);
         sb.append(publicModifier);
         sb.append(staticValue);
         sb.append("function ");
diff --git a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/MethodReference.java b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/MethodReference.java
index 218e910..df02449 100644
--- a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/MethodReference.java
+++ b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/MethodReference.java
@@ -31,6 +31,7 @@
 import com.google.javascript.rhino.JSTypeExpression;
 import com.google.javascript.rhino.Node;
 import com.google.javascript.rhino.jstype.JSType;
+import com.google.javascript.rhino.jstype.JSType.Nullability;
 
 public class MethodReference extends MemberReference
 {
@@ -69,7 +70,7 @@
     public String toReturnTypeAnnotationString()
     {
         JSType jsType = getModel().evaluate(getComment().getReturnType());
-        return jsType.toAnnotationString();
+        return jsType.toAnnotationString(Nullability.EXPLICIT);
     }
 
     public MethodReference(ReferenceModel model, ClassReference classReference, Node node, String name,
diff --git a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/ReferenceModel.java b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/ReferenceModel.java
index f0fcd24..1fe4d5c 100644
--- a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/ReferenceModel.java
+++ b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/reference/ReferenceModel.java
@@ -37,6 +37,7 @@
 import com.google.javascript.rhino.JSTypeExpression;
 import com.google.javascript.rhino.Node;
 import com.google.javascript.rhino.jstype.JSType;
+import com.google.javascript.rhino.jstype.TemplatizedType;
 
 public class ReferenceModel
 {
@@ -328,6 +329,10 @@
             try
             {
                 jsType = expression.evaluate(null, jscompiler.getTypeRegistry());
+                if (jsType.isTemplatizedType())
+                {
+                	jsType = ((TemplatizedType)jsType).getReferencedType();
+                }
             }
             catch (Exception e)
             {
diff --git a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/utils/JSTypeUtils.java b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/utils/JSTypeUtils.java
index a2f85ee..2dd8ec5 100644
--- a/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/utils/JSTypeUtils.java
+++ b/compiler-externc/src/main/java/org/apache/royale/compiler/internal/codegen/typedefs/utils/JSTypeUtils.java
@@ -29,7 +29,9 @@
 import com.google.javascript.rhino.JSTypeExpression;
 import com.google.javascript.rhino.jstype.JSType;
 import com.google.javascript.rhino.jstype.NamedType;
+import com.google.javascript.rhino.jstype.TemplatizedType;
 import com.google.javascript.rhino.jstype.UnionType;
+import com.google.javascript.rhino.jstype.JSType.Nullability;
 
 public class JSTypeUtils
 {
@@ -92,7 +94,7 @@
     public static String toEnumTypeString(BaseReference reference)
     {
         JSTypeExpression enumParameterType = reference.getComment().getEnumParameterType();
-        String overrideStringType = transformType(reference.getModel().evaluate(enumParameterType).toAnnotationString());
+        String overrideStringType = transformType(reference.getModel().evaluate(enumParameterType).toAnnotationString(Nullability.EXPLICIT));
 
         return overrideStringType;
     }
@@ -167,6 +169,10 @@
         {
             return "* /* " + type + " */";
         }
+        else if (jsType.isTemplatizedType())
+        {
+        	return ((TemplatizedType)jsType).getReferencedType().toString();
+        }
         else
         {
             if (type.indexOf("Array<") == 0)
diff --git a/compiler-externc/src/test/build.xml b/compiler-externc/src/test/build.xml
index 9e11013..8c79786 100644
--- a/compiler-externc/src/test/build.xml
+++ b/compiler-externc/src/test/build.xml
@@ -88,7 +88,6 @@
                 <fileset dir="${compiler.externc}/target/test-classes">
                     <!-- externs tests -->
                     <include name="**/TestExternES3.class"/>
-                    <include name="**/TestExternChrome.class"/>
                     <include name="**/TestExternJSMissing.class"/>
                     <include name="**/TestAnnotationEnum.class"/>
                     <include name="**/TestCollectImports.class"/>
diff --git a/compiler-externc/src/test/config/externc-config.xml b/compiler-externc/src/test/config/externc-config.xml
index 3171696..ee1ed35 100644
--- a/compiler-externc/src/test/config/externc-config.xml
+++ b/compiler-externc/src/test/config/externc-config.xml
@@ -67,7 +67,6 @@
 
         <path-element>../../../target/downloads/browser/whatwg_encoding.js</path-element>
 
-        <path-element>../../../target/downloads/browser/chrome.js</path-element>
         <!-- path-element>../../../target/downloads/browser/fetchapi.js</path-element>-->
         <path-element>../../../target/downloads/browser/fileapi.js</path-element>
         <path-element>../../../target/downloads/browser/flash.js</path-element>
@@ -107,6 +106,7 @@
     <class-exclude>
         <class>controlRange</class>
         <class>ITemplateArray</class>
+        <class>Symbol</class>
     </class-exclude>
     
     <!-- Object.toString() is excluded by the ExternC compiler.  Otherwise
@@ -156,6 +156,14 @@
         <class>Document</class>
         <name>createTreeWalker</name>
     </exclude>
+    <exclude>
+        <class>AsyncGenerator</class>
+        <name>next</name>
+    </exclude>
+    <exclude>
+        <class>Generator</class>
+        <name>next</name>
+    </exclude>
     <!-- SVG -->
     <exclude><class>SVGStylable</class><name>className</name></exclude>
     <exclude><class>SVGStylable</class><name>style</name></exclude>
diff --git a/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestConstructor.java b/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestConstructor.java
index 099ec7d..6455ffa 100644
--- a/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestConstructor.java
+++ b/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestConstructor.java
@@ -30,6 +30,8 @@
 import org.apache.royale.compiler.internal.codegen.typedefs.reference.ClassReference;
 import org.junit.Test;
 
+import com.google.javascript.rhino.jstype.JSType.Nullability;
+
 public class TestConstructor extends TypedefsTestBase
 {
 
@@ -82,13 +84,13 @@
 
         assertEquals(
                 "number",
-                evaluateParam(FooOptVarArgs.getConstructor(), "arg1").toAnnotationString());
+                evaluateParam(FooOptVarArgs.getConstructor(), "arg1").toAnnotationString(Nullability.EXPLICIT));
         assertEquals(
                 "*",
-                evaluateParam(FooOptVarArgs.getConstructor(), "opt_arg2").toAnnotationString());
+                evaluateParam(FooOptVarArgs.getConstructor(), "opt_arg2").toAnnotationString(Nullability.EXPLICIT));
         assertEquals(
                 "*",
-                evaluateParam(FooOptVarArgs.getConstructor(), "var_args").toAnnotationString());
+                evaluateParam(FooOptVarArgs.getConstructor(), "var_args").toAnnotationString(Nullability.EXPLICIT));
     }
 
     @Test
diff --git a/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestExternChrome.java b/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestExternChrome.java
deleted file mode 100644
index f7bb0d3..0000000
--- a/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestExternChrome.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- *
- *  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.royale.compiler.internal.codegen.typedefs;
-
-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.royale.compiler.clients.ExternCConfiguration;
-import org.apache.royale.compiler.internal.codegen.typedefs.reference.ClassReference;
-import org.apache.royale.compiler.problems.ICompilerProblem;
-import org.junit.Test;
-
-import com.google.javascript.jscomp.Result;
-
-public class TestExternChrome extends TypedefsTestBase
-{
-    @Test
-    public void test_classes() throws IOException
-    {
-        client.cleanOutput();
-        Result result = compile();
-        assertTrue(result.success);
-        if (model.problems.getProblems().size() > 0)
-        {
-        	for (ICompilerProblem problem : model.problems.getProblems())
-        		System.out.println(problem.toString() + " " + problem.getSourcePath() + " " + problem.getLine());        	
-        }
-        assertEquals(0, model.problems.getProblems().size());
-
-        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(322, 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);
-        if (model.problems.getProblems().size() > 0)
-        {
-        	for (ICompilerProblem problem : model.problems.getProblems())
-        		System.out.println(problem.toString() + " " + problem.getSourcePath() + " " + problem.getLine());        	
-        }
-        assertEquals(0, model.problems.getProblems().size());
-
-        // 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
-    {
-    	TypedefsTestUtils.init();
-        config.setASRoot(TypedefsTestUtils.AS_ROOT_DIR);
-
-        String coreRoot = TypedefsTestUtils.TYPEDEFS_JS_DIR.getAbsolutePath();
-        config.addTypedef(coreRoot + "/es3.js");
-        config.addTypedef(coreRoot + "/es6.js");
-        config.addTypedef(coreRoot + "/browser/chrome.js");
-        config.addTypedef(coreRoot + "/browser/html5.js");
-        config.addTypedef(coreRoot + "/browser/ie_dom.js");
-        config.addTypedef(coreRoot + "/browser/gecko_dom.js");
-        config.addTypedef(coreRoot + "/browser/w3c_css.js");
-        config.addTypedef(coreRoot + "/browser/w3c_event.js");
-        config.addTypedef(coreRoot + "/browser/w3c_range.js");
-        config.addTypedef(coreRoot + "/browser/w3c_dom1.js");
-        config.addTypedef(coreRoot + "/browser/w3c_dom2.js");
-        config.addTypedef(coreRoot + "/browser/w3c_dom3.js");
-        config.addTypedef(coreRoot + "/browser/w3c_xml.js");
-    }
-
-}
diff --git a/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestExternES3.java b/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestExternES3.java
index 3acc4b0..e2a65c1 100644
--- a/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestExternES3.java
+++ b/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestExternES3.java
@@ -60,7 +60,7 @@
                 "Math" };
 
         // IObject and IArrayLike are two extras
-        assertEquals(23, model.getClasses().size());
+        assertEquals(24, model.getClasses().size());
         for (String className : classes)
         {
             assertTrue(model.hasClass(className));
diff --git a/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestExternJasmine.java b/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestExternJasmine.java
index 233643b..e9b85f7 100644
--- a/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestExternJasmine.java
+++ b/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestExternJasmine.java
@@ -41,7 +41,7 @@
                 "jasmine",
                 "jasmine.Clock"};
 
-        assertEquals(9, model.getClasses().size());
+        assertEquals(10, model.getClasses().size());
         for (String className : classes)
         {
             assertTrue(model.hasClass(className));
diff --git a/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestTypeTypedefs.java b/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestTypeTypedefs.java
index b94ff5d..a631106 100644
--- a/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestTypeTypedefs.java
+++ b/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TestTypeTypedefs.java
@@ -82,7 +82,7 @@
                 JSTypeUtils.toParamTypeString(reference.getStaticMethod("test4"), "arg1"));
         assertEquals("Object",
                 JSTypeUtils.toParamTypeString(reference.getStaticMethod("test5"), "arg1"));
-        assertEquals("Function /* function (string, boolean): ? */",
+        assertEquals("Function /* function(string, boolean): ? */",
                 JSTypeUtils.toParamTypeString(reference.getStaticMethod("test6"), "arg1"));
     }
 
diff --git a/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TypedefsTestUtils.java b/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TypedefsTestUtils.java
index 87daab5..0378c14 100644
--- a/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TypedefsTestUtils.java
+++ b/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TypedefsTestUtils.java
@@ -174,7 +174,6 @@
 
         config.addTypedef(coreRoot + "/browser/whatwg_encoding.js");
 
-        config.addTypedef(coreRoot + "/browser/chrome.js");
         //config.addTypedef(coreRoot + "/browser/fetchapi.js");
         config.addTypedef(coreRoot + "/browser/fileapi.js");
         config.addTypedef(coreRoot + "/browser/flash.js");
diff --git a/compiler-externc/src/test/resources/typedefs/unit_tests/missing.js b/compiler-externc/src/test/resources/typedefs/unit_tests/missing.js
index 689f185..d868582 100644
--- a/compiler-externc/src/test/resources/typedefs/unit_tests/missing.js
+++ b/compiler-externc/src/test/resources/typedefs/unit_tests/missing.js
@@ -311,3 +311,34 @@
  * @type {number}
  */
 Date.prototype.timezoneOffset;
+
+/**
+ * @param {string} type
+ * @param {EventListener|function(!Event):*} listener
+ * @param {(boolean|!AddEventListenerOptions)=} opt_options
+ * @return {undefined}
+ * @see https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener
+ */
+BaseAudioContext.prototype.addEventListener = function(type, listener, opt_options) {
+};
+
+/**
+ * @param {string} type
+ * @param {EventListener|function(!Event):*} listener
+ * @param {(boolean|!EventListenerOptions)=} opt_options
+ * @return {undefined}
+ * @see https://dom.spec.whatwg.org/#dom-eventtarget-removeeventlistener
+ */
+BaseAudioContext.prototype.removeEventListener = function(
+    type, listener, opt_options) {};
+	
+/**
+ * @param {!Event} evt
+ * @return {boolean}
+ * @see https://dom.spec.whatwg.org/#dom-eventtarget-dispatchevent
+ */
+BaseAudioContext.prototype.dispatchEvent = function(evt) {};
+
+
+
+
diff --git a/compiler-jburg-types/build.xml b/compiler-jburg-types/build.xml
index 9076f9b..2855b94 100644
--- a/compiler-jburg-types/build.xml
+++ b/compiler-jburg-types/build.xml
@@ -66,8 +66,10 @@
             <compilerarg value="-Xlint:all,-path,-fallthrough"/>
             <src path="${compiler-jburg-types}/src/main/java"/>
             <include name="org/apache/royale/compiler/internal/as/codegen/IASNodeAdapter.java"/>
+            <include name="jburg/burg/JBurgGenerator.java"/>
             <classpath>
                 <pathelement location="${compiler-jburg-types}/../compiler/lib/external/jburg.jar"/>
+                <pathelement location="${compiler-jburg-types}/../compiler/lib/external/antlr.jar"/>
             </classpath>
         </javac>
 	</target>
diff --git a/compiler-jburg-types/pom.xml b/compiler-jburg-types/pom.xml
index 885e49f..603b9f7 100644
--- a/compiler-jburg-types/pom.xml
+++ b/compiler-jburg-types/pom.xml
@@ -30,17 +30,97 @@
 
   <groupId>org.apache.royale.compiler</groupId>
   <artifactId>compiler-jburg-types</artifactId>
-  <version>1.0.0</version>
+  <version>1.1.0</version>
 
   <name>Apache Royale: JBurg Types</name>
   <description>Types needed by JBurg to perform it's code generation.</description>
 
+  <build>
+    <plugins>
+        <plugin>
+            <groupId>io.github.zlika</groupId>
+            <artifactId>reproducible-build-maven-plugin</artifactId>
+            <version>0.9</version>
+        </plugin>
+        <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-javadoc-plugin</artifactId>
+            <version>2.10.4</version>
+        </plugin>
+    </plugins>
+    <pluginManagement>
+        <plugins>
+            <plugin>
+                <groupId>io.github.zlika</groupId>
+                <artifactId>reproducible-build-maven-plugin</artifactId>
+                <version>0.9</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>strip-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>2.10.4</version>
+                <configuration>
+                    <tags>
+                        <tag>
+                            <name>goal</name>
+                            <placement>a</placement>
+                            <head>Goal:</head>
+                        </tag>
+                        <tag>
+                            <name>phase</name>
+                            <placement>a</placement>
+                            <head>Phase:</head>
+                        </tag>
+                        <tag>
+                            <name>threadSafe</name>
+                            <placement>a</placement>
+                            <head>Thread Safe:</head>
+                        </tag>
+                        <tag>
+                            <name>requiresDependencyResolution</name>
+                            <placement>a</placement>
+                            <head>Requires Dependency Resolution:</head>
+                        </tag>
+                        <tag>
+                            <name>requiresProject</name>
+                            <placement>a</placement>
+                            <head>Requires Project:</head>
+                        </tag>
+                        <tag>
+                            <name>note</name>
+                            <placement>a</placement>
+                            <head>note:</head>
+                        </tag>
+                        <tag>
+                            <name>pre</name>
+                            <placement>X</placement>
+                            <head></head>
+                        </tag>
+                    </tags>
+                </configuration>
+            </plugin>
+        </plugins>
+    </pluginManagement>
+  </build>
+
   <dependencies>
     <dependency>
       <groupId>net.sourceforge.jburg</groupId>
       <artifactId>jburg</artifactId>
       <version>1.10.3</version>
     </dependency>
+    <dependency>
+      <groupId>antlr</groupId>
+      <artifactId>antlr</artifactId>
+      <version>2.7.7</version>
+    </dependency>
   </dependencies>
 
 </project>
diff --git a/compiler-jburg-types/src/main/java/jburg/burg/JBurgGenerator.java b/compiler-jburg-types/src/main/java/jburg/burg/JBurgGenerator.java
new file mode 100644
index 0000000..a20c056
--- /dev/null
+++ b/compiler-jburg-types/src/main/java/jburg/burg/JBurgGenerator.java
@@ -0,0 +1,3763 @@
+/*
+ *
+ *  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 jburg.burg;
+
+//  BURM specification is parsed into ANTLR2 AST objects.
+import antlr.collections.AST;
+
+//  The code emitter interface definition.
+import jburg.burg.emitlangs.EmitLang;
+
+//  The factory that selects and creates an emitter.
+import jburg.burg.emitlangs.JBurgEmitterFactory;
+
+//  The i-node adapter interface definition.
+import jburg.burg.inode.InodeAdapter;
+import jburg.burg.inode.InodeAdapter2;
+//  Interface for i-node adapters that need
+//  to emit support routines.
+import jburg.burg.inode.InodeAuxiliarySupport;
+
+//  The factory that selects and creates an I-node adapter.
+import jburg.burg.inode.InodeAdapterFactory;
+
+//  Token types from ANTLR.
+import jburg.parser.JBurgTokenTypes;
+
+//  Version file, generated by build.
+import jburg.generator.version.JBurgVersion;
+
+
+import java.io.PrintStream;
+
+import java.lang.reflect.Modifier;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Vector;
+
+
+@SuppressWarnings("nls")
+public class JBurgGenerator implements JBurgTokenTypes
+{
+    /**
+     *  The JBurg specification's rules are categorized as:
+     *  <ul>
+     *  <li> Pattern  (e.g., integer = PLUS(integer, integer) )
+     *  <li> Simple Transformational   (e.g., registerOperand  = integer)
+     *  <li> Complex Transformational  (e.g., string = integer { code to convert integer to string} )
+     *  </ul>
+     *
+     *  Simple transformational rules allow a subgoal to satisfy
+     *  other subgoals without additional processing; complex
+     *  transformational rules allow one subgoal to feed additional
+     *  processing that can satisfy other subgoals (at added cost).
+     *
+     *  Syntactically, a simple transformational rule is distinguished 
+	 *  by its lack of a block of code.
+	 *  Simple transformational rules are also known as "chain rules"
+	 *  in simpler BURGs that don't support complex transformational
+	 *  rules.  This longer name was adopted to highlight that difference,
+	 *  but a simple transformational rule is, in fact, a chain rule
+	 *  by a different name.
+     */
+
+	/**
+     *   The table of all transformation rules; keyed
+     *   by the rules' necessary state, e.g., integer
+	 *   in the rule number = integer).
+     */
+    Map<String, Vector<JBurgRule>> transformationRules = new HashMap<String, Vector<JBurgRule>>();
+
+	/**
+	 *  The table of all pattern rules, keyed
+	 *  by the top-level operator of the pattern,
+	 *  e.g., PLUS in the pattern integer = PLUS(integer, integer).
+	 */
+    Map<String, Vector<JBurgRule>> patternRules = new HashMap<String, Vector<JBurgRule>>();
+
+    /**
+     *  The goal states' names become symbolic constants
+     *  in the generated reducer.
+     */
+    Set<String> allGoalStates = new HashSet<String>();
+
+    /**
+     *  Closure sets are organized by their goal state; each state's
+     *  closure set contains an entry for every closure
+     *  path from any other non-terminal state to the target state.
+     */
+    Map<String, Vector<ClosureRecord>> closureSets = new HashMap<String, Vector<ClosureRecord>>();
+
+    /**  Action code fragments.  */
+    ArrayList<JBurgReduceAction> reduceActions = new ArrayList<JBurgReduceAction>();
+
+    /**
+     *  Cost function fragments.
+     *  Note that cost functions may also be embedded
+     *  in the inline code blocks in a specification.
+     */
+    ArrayList<AST> costFunctions = new ArrayList<AST>();
+
+    /**  The names of any interfaces that the generated BURM implements.  */
+    Vector<String> interfaceNames = new Vector<String>();
+    
+    /** blocks of code to be added into the class verbatim */
+    Vector<String> inclassCode = new Vector<String>();
+
+    /**
+     *  Rules that can generate compressed annotations.
+     */
+    RulesByOperatorAndArity compressedAnnotations = new RulesByOperatorAndArity();
+
+    /** The package name of the generated reducer. */
+    String packageName = null;
+
+    /**  Header code, copied as-is into the reducer. */
+    String headerBlock = null;
+
+    /**
+     *  The name of the i-node class that's being labeled and reduced.
+     */
+    String iNodeClass = null;
+
+	/** 
+	 *  I-node adapter class name.  The adapter is instantiated by name.
+	 *  @note: specified as an alternative to the I-node class' name,
+	 *  which selects a builtin adapter.
+	 */
+	String iNodeAdapterClass;
+
+    /**
+     *  The return types for specific states.
+     */
+    Map<String, String> returnTypeTable = new HashMap<String, String>();
+
+    /**
+     *  The default return type of the reducer functions.
+     *  If this is defaulted to null, the generated reducer will return nodes of the iNodeClass.
+     */
+    String defaultReturnType = null;
+
+    /**
+     *  Table of properties to be added to the BURM.
+     *  Each one is a name/type pair; the BURM gets
+     *  a private member and get/set methods.
+     */
+    Map<String, String> burmProperties = new HashMap<String, String>();
+
+    /**
+     *  Simple transformations simply delegate to their antecedent reduction,
+     *  so all transformations to a given nonterminal state can share the
+     *  same rule.
+     */
+    Map<String, JBurgRule> simpleTransformationRules = new HashMap<String,JBurgRule>();
+
+    /**  Include debugging code in the generated reducer?  */
+    boolean debugMode;
+    
+    /** 
+     * If the pattern-matcher generator fails, dump its annotation tree here.
+     * Note: this is only enabled (or useful) when debugging JBurg's own BURM. 
+     */
+    String patternMatcherDumpFile = null;
+
+    /**  
+     *  Caller's logging interface.  If defaulted to null, informational and
+     *  error messages go to System.out and System.err respectively.
+     */
+    Logger logger = null;
+    
+    /**
+     * Name for the language to emit code in (default is assumed to be java (=emitlang.EmitJava)
+     */
+    String emitLanguageName = null;
+    
+    /** Code emitter to use (selected using the language name) */
+	EmitLang codeEmitter = null;
+
+	/** I-node adapter to use */
+	InodeAdapter iNodeAdapter;
+	
+	/** 
+	 *  If the InodeAdapter is also an InodeAdapter2,
+	 *  keep a reference to it. 
+	 */
+	InodeAdapter2 adapter2;
+
+	/**  Cumulative error count. */
+	int errCount = 0;
+
+	/**  Name of the initial parameter to the label routine. */
+	private static String initalParamName = "to_be_labelled";
+	
+	/** Name of the node in the reducer */
+	private String reducerNodeName = "__p";
+	
+	/** Name of the stack of reduced values */
+	private String reducedValuesName = "__reducedValues";
+
+    /**  Default error handler.  null means use hard-coded default, i.e., throw an exception. */
+    String defaultErrorHandler = null;
+
+    /**  Prologue snippets mapped to the corresponding rule number. */
+    Map<Integer,String> prologueBlocks = new TreeMap<Integer,String>();
+
+    /** 
+     *  All operators known to any pattern accumulate in this set
+     *  so that the BURG can generate operator-specific getNthChild()
+     *  routines.
+     */
+    Set<String> allOperators = new TreeSet<String>();
+    
+    /**
+     * operator mapped to node type. This map is populated by JBurg.NodeType
+     * directives.
+     * <p>
+     * For example, an operator named IdentifierID would be associated with
+     * {@code IIdentifierNode*} in this map if the input contained
+     * {@code JBurg.NodeType IdentifierID = IIdentifierNode*;
+     */
+    final Map<String, String> opcodeNodeTypes = new HashMap<String, String>();
+    
+    /**
+     *  The type of the INodes' opcode.  Defaults to int but
+     *  can be an enum for maintainability.
+     */
+    String opcodeType = "int";
+
+    /**
+     *  Manifest constants in the JBurg specification.
+     */
+    Map<String,Integer> manifestConstants = new HashMap<String,Integer>();
+    
+    /**
+     *  Patterns that have been optimized out are represented
+     *  by this not-likely-to-compile sequence.
+     */
+    final private static String nilPattern = "-null-";
+
+    /**
+     *  Manifest constant for method declarations.
+     */
+    final private static Class<?>[] throwsNothing = null;
+
+    /**
+     *  Manifest constant for method declarations.
+     */
+    final private static Class<?>[] throwsException = new Class<?>[] { Exception.class };
+
+
+    /**
+     *  Manifest constant for method declarations.
+     */
+    final private static String[][] noFormalParameters = new String[][] { };
+
+    /**
+     *  Manifest constant for method calls.
+     */
+    final private static String[] noActualParameters = { };
+
+    /**
+     *  Manifest constant for an unfeasible rule.
+     */
+    final private static String NO_FEASIBLE_RULE = "-1";
+
+    /**
+     *  Manifest constant for an uninitialized cost.
+     */
+    final private static String UNINITIALIZED = "-1";
+
+    /**
+     *  NamedPattern holds a named pattern, and keeps a table of the reductions that refer to it.
+     *  (See defect 3063143 for problems with multiple reductions sharing a pattern.)
+     */
+    class NamedPattern
+    {
+        String patternName;
+        AST pattern = null;
+        Vector<AST> reductions = new Vector<AST>();
+
+        NamedPattern(String name)
+        {
+            this.patternName = name;
+        }
+    }
+
+    /**
+     *  A PatternMap keeps the map of pattern names to reductions.
+     */
+    @SuppressWarnings("serial")
+    class PatternMap extends  TreeMap<String,NamedPattern>
+    {
+        NamedPattern getPattern(String key)
+        {
+            if ( !super.containsKey(key) )
+                put(key, new NamedPattern(key));
+            return super.get(key);
+        }
+
+        void addPattern(String key, AST pattern)
+        {
+            NamedPattern p = getPattern(key);
+            p.pattern = pattern;
+        }
+
+        void addReduction(String key, AST reduction)
+        {
+            NamedPattern p = getPattern(key);
+            p.reductions.add(reduction);
+        }
+    }
+
+    PatternMap namedPatterns = new  PatternMap();
+
+    /**
+     *  Aggregate path computations if more than this threshold
+     *  number of pattern elements share a path.
+     */
+    private int aggregatePathThreshold = Integer.MAX_VALUE;
+
+    public void setAggregatePathThreshold(int threshold)
+    {
+        this.aggregatePathThreshold = threshold;
+    }
+
+    /**
+      *  @param root - the root of the AST generated by parsing the .jburg specification.
+      */
+    public JBurgGenerator(AST root, Logger log) throws Exception
+    {
+        this.logger = log;
+
+        //  Walk over the children of the root, each of which 
+		//  is a self-contained syntactical construct, and
+        //  find an appropriate action for each.
+        for (AST currentNode = root; currentNode != null;
+                currentNode = currentNode.getNextSibling()) 
+		{
+            switch (currentNode.getType()) 
+			{
+            case COST_FUNCTION:
+                this.costFunctions.add(currentNode);
+                break;
+
+            case HEADER_DECLARATION:
+
+				if ( null == this.headerBlock )
+				{
+					this.headerBlock = getCodeBlock(currentNode);
+				}
+				else
+				{
+                    throw new IllegalArgumentException("The class header may only be specified once.");
+				}
+
+                break;
+                
+            case INCLASS_DECLARATION:
+				{
+            		this.inclassCode.add( stripBrackets(getCodeBlock(currentNode)) );
+            	}
+				
+				break;
+
+            case INODE_ADAPTER_DECLARATION:
+
+                if (this.iNodeAdapterClass == null)
+				{
+					this.iNodeAdapterClass = getIdentifierText(currentNode.getFirstChild());
+				}
+				else
+				{
+                    throw new IllegalArgumentException("INodeAdapter may only be specified once.");
+				}
+
+				break;
+
+            case INODE_TYPE_DECLARATION:
+
+                if (this.iNodeClass == null)
+				{
+                    this.iNodeClass = getIdentifierText(currentNode.getFirstChild());
+				}
+                else
+				{
+                    throw new IllegalArgumentException("INodeType may only be specified once.");
+				}
+
+                break;
+                
+            case LANGUAGE_DECLARATION:
+
+            	if ( null == this.emitLanguageName )
+				{
+            		this.emitLanguageName = currentNode.getFirstChild().getText();
+				}
+            	else
+				{
+            		throw new IllegalArgumentException("Language may only be specified once.");
+				}
+
+            	break;
+
+            case IMPLEMENTS_INTERFACE_SPECIFICATION:
+                this.interfaceNames.addElement(getIdentifierText( currentNode.getFirstChild()) );
+
+                break;
+
+            case PACKAGE_SPECIFICATION:
+                if ( null == this.packageName )
+				{
+					this.packageName = getIdentifierText(currentNode.getFirstChild());
+				}
+				else
+				{
+            		throw new IllegalArgumentException("package may only be specified once.");
+				}
+
+                break;
+
+            case PROPERTY_SPECIFICATION: 
+				{
+					String propertyType = getIdentifierText(currentNode.getFirstChild());
+					String propertyName = currentNode.getFirstChild().getNextSibling().getText();
+					this.burmProperties.put(propertyName, propertyType);
+				}
+
+                break;
+
+            case RETURN_DECLARATION:
+
+                if (this.defaultReturnType == null)
+                    this.defaultReturnType = getIdentifierText(currentNode.getFirstChild());
+                else
+                    throw new IllegalArgumentException( "ReturnType may only be specified once.");
+
+                break;
+
+            case PATTERN_RULE:
+                addPatternRule(currentNode);
+
+                break;
+
+            case SIMPLE_TRANSFORMATION_RULE:
+                addSimpleTransformationRule(currentNode);
+
+                break;
+
+            case TRANSFORMATION_RULE:
+                addComplexTransformationRule(currentNode);
+
+                break;
+
+            case TYPED_RETURN_DECLARATION:
+
+                {
+                    String stateName = currentNode.getFirstChild().getText();
+                    String returnType = getIdentifierText(currentNode.getFirstChild()
+                            .getNextSibling());
+
+                    //  Put the return declaration in the table, but only once per state.
+                    Object typeCollision = this.returnTypeTable.put(stateName, returnType);
+                    if ( null != typeCollision )
+                    {
+                        throw new IllegalArgumentException(
+                            "A state may only specify one ReturnType."
+                        );
+                    }
+                }
+
+                break;
+
+            case PATTERN_DECLARATION:
+                {
+                    String pattern_name = currentNode.getFirstChild().getText();
+                    namedPatterns.addPattern(pattern_name, currentNode);
+                }
+                break;
+
+            case REDUCTION_DECLARATION:
+                {
+                    String pattern_name = currentNode.getFirstChild().getNextSibling().getText();
+                    namedPatterns.addReduction(pattern_name, currentNode);
+                }
+                break;
+
+            case DEFAULT_ERROR_HANDLER:
+                this.defaultErrorHandler = getCodeBlock(currentNode);
+                break;
+            case NODE_TYPE:
+            {
+                final String operatorID = currentNode.getFirstChild().getText();
+                assert !operatorID.isEmpty() : "Parser should never create empty operator!";
+                final String nodeType = currentNode.getFirstChild().getNextSibling().getText();               
+                assert !nodeType.isEmpty() : "Parser should never create empty node type!";
+                
+                if (this.opcodeNodeTypes.put(operatorID, nodeType) != null)
+                {
+                    final String message = "Duplicate node type declaration for '"
+                        + operatorID
+                        + "'.";
+                    throw new IllegalArgumentException(message);
+                }
+                break;
+            }
+            case OPCODE_TYPE:
+                this.opcodeType = currentNode.getFirstChild().getText();
+                break;
+
+            case MANIFEST_CONSTANT:
+                manifestConstants.put(currentNode.getFirstChild().getText(), Integer.parseInt(currentNode.getFirstChild().getNextSibling().getText()));
+                break;
+
+            default:
+                throw new IllegalArgumentException("Unknown specification AST type " +
+            											String.valueOf(currentNode.getType()));
+            }
+        }
+
+        //  Set the language emitter.
+        codeEmitter = JBurgEmitterFactory.getEmitter(emitLanguageName, getLogger());
+
+        if ( codeEmitter == null )
+		{
+			throw new IllegalStateException("Unknown language specified: \""+ emitLanguageName +"\"");
+        }
+
+		if ( iNodeClass != null )
+		{
+			if ( iNodeAdapterClass != null )
+			{
+				try
+				{
+					this.iNodeAdapter = (InodeAdapter)Class.forName(iNodeAdapterClass).newInstance();
+				}
+				catch ( Exception ex )
+				{
+					ex.printStackTrace();
+					throw new IllegalArgumentException ("Unable to instantiate i-node adapter " + iNodeAdapterClass );
+				}
+			}
+			else
+			{
+				this.iNodeAdapter = InodeAdapterFactory.getAdapter(iNodeClass);
+			}
+			
+			codeEmitter.setINodeType(this.iNodeClass);
+
+			if ( this.iNodeAdapter != null )
+			{
+				logger.info("Using i-node adapter " + this.iNodeAdapter.getClass().getName() );
+			}
+			else
+			{
+				getLogger().warning("using default i-node adapter, no adapter matches " + iNodeClass );
+				this.iNodeAdapter = new jburg.burg.inode.DefaultAdapter();
+			}
+			
+			//  See if the adapter is also an InodeAdapter2 implementation.
+			this.adapter2 = (this.iNodeAdapter instanceof InodeAdapter2)? (InodeAdapter2)this.iNodeAdapter : null;
+		}
+		else
+		{
+			throw new IllegalStateException("You must specify the i-node type.");
+		}
+
+		codeEmitter.setInodeAdapter(this.iNodeAdapter);
+
+        //  Default return type is the same as the INode class.
+        if (this.defaultReturnType == null)
+		{
+            this.defaultReturnType = this.iNodeClass;
+		}
+
+        //  Mutate pattern/reduction decl pairs into pattern rules.
+        for ( NamedPattern np: namedPatterns.values() )
+        {
+            if ( np.pattern != null && np.reductions.size() > 0 )
+            {
+                AST named_pattern = np.pattern.getFirstChild().getNextSibling().getFirstChild();
+
+                for ( AST reduction: np.reductions )
+                {    
+                    //  Splice the pattern into the reduction AST.
+                
+                    AST nt_state = reduction.getFirstChild();
+                    AST pattern_name = nt_state.getNextSibling();
+                    AST cost_decl = pattern_name.getNextSibling();
+                    
+                    //  Create a new holder for the pattern
+                    //  so the original AST isn't mutated.
+                    AST pattern_holder = new antlr.CommonAST();
+                    pattern_holder.setFirstChild(named_pattern);
+                    nt_state.setNextSibling(pattern_holder);
+                    pattern_holder.setNextSibling(cost_decl);
+    
+                    //  Give the composite AST the appropriate type
+                    //  for its pattern.
+                    reduction.setType(PATTERN_RULE);
+    
+                    addPatternRule(reduction);
+                }
+            }
+            else if ( np.pattern != null )
+            {
+                getLogger().warning("pattern " + np.patternName + " has no reduction - ignored.");
+            }
+            else if ( np.reductions.size() > 0 )
+            {
+                throw new IllegalStateException("Reduction " + np.patternName + " has no associated pattern.");
+            }
+        }
+
+        //  Add target-specific logic to the simple transformations' rules.
+        for ( JBurgRule rule: this.simpleTransformationRules.values() )
+        {
+            String actionCode = String.format(
+                "%s%s",
+                codeEmitter.genReturnValue(
+                    codeEmitter.genPopFromStack(reducedValuesName, getReturnType(rule.getGoalState()))
+                ),
+                codeEmitter.genEndStmt()
+            );
+
+            JBurgReduceAction action = addAction(actionCode, rule.getGoalState());
+            action.setAntecedentState(rule.getAntecedentState());
+            rule.setReduceAction(action);
+        }
+
+        //  Compute the closure sets.
+        computeClosureSets();
+    }
+    
+    /**
+     *  Add a reduce action to the action list.
+	 *  Actions are keyed by number in the generated BURM.
+     */
+    private JBurgReduceAction addAction(String strAction, String strState)
+    {
+        JBurgReduceAction newAction = new JBurgReduceAction(strAction);
+        this.reduceActions.add(newAction);
+
+        //  The first index is used as the default action for
+        //  simple transformation rules.
+        newAction.setIndex(this.reduceActions.size());
+        newAction.setState(strState);
+
+        return newAction;
+    }
+
+    /**
+     *  Sort through a rule's action routine specifications and assemble
+     *  a JBurgReduceAction from them.
+     *  @param parent - the rule's AST.
+     *  @param goal_state - the state the rule produces.
+     *  
+     */
+    private JBurgReduceAction decodeReduction(AST parent, String goal_state)
+    {
+        JBurgReduceAction action = null;
+        AST reduction = null;
+
+        if ( hasASTOfType(parent, REDUCTION_ACTION) )
+        {
+            reduction = getASTByType(parent, REDUCTION_ACTION);
+            action = addAction(getCodeBlock(reduction), goal_state);
+        }
+        else if ( hasASTOfType(parent, EXPLICIT_REDUCTION ) )
+        {
+            reduction = getASTByType(parent, EXPLICIT_REDUCTION);
+            action = addAction( "return " + decodeProcedureCall(reduction) + ";", goal_state );
+        }
+        else
+        {
+            throw new IllegalStateException("A reduction must specify an implementation block or callback function");
+        }
+
+        if ( hasASTOfType(reduction, PROLOGUE) )
+        {
+            AST prologue = getASTByType(reduction, PROLOGUE);
+            String prologue_action = null;
+
+            if ( hasASTOfType(prologue, BLOCK) )
+            {
+                prologue_action = getCodeBlock(prologue);
+            }
+            else if ( hasASTOfType(prologue, PROCEDURE_CALL) )
+            {
+                prologue_action = "\t" + decodeProcedureCall(prologue) + ";";
+            }
+            else
+            {
+                throw new IllegalStateException("Prologue block with no inline code or callback");
+            }
+
+            this.prologueBlocks.put(action.index, prologue_action);
+        }
+
+        return action;
+    }
+
+    private String decodeProcedureCall(AST parent)
+    {
+        AST procall = getASTByType(parent, PROCEDURE_CALL);
+
+        StringBuilder buffer = new StringBuilder();
+
+        AST id = procall.getFirstChild();
+        buffer.append(id.getText());
+        buffer.append("(");
+
+        AST param = id.getNextSibling();
+        if ( param != null )
+        {
+            buffer.append(param.getText());
+
+            for ( param = param.getNextSibling(); param != null; param = param.getNextSibling() )
+            {
+                buffer.append(",");
+                buffer.append(param.getText());
+            }
+        }
+        buffer.append(")");
+
+        return buffer.toString();
+    }
+
+    /**
+     *  Add a complex transformation rule to its table,
+     *  and record the rule's reduction action.
+     */
+    private void addComplexTransformationRule(AST transform)
+        throws Exception
+    {
+        JBurgRule n = addNamedRule(this.transformationRules, transform);
+
+        //  Prepare the rule's reduce action.
+        JBurgReduceAction action = decodeReduction(transform, n.getGoalState());
+        action.setAntecedentState(n.getAntecedentState());
+
+        //  Add the antecedent state by name as an alias action routine "parameter."
+        //  The "parameter" is popped off the reduced values stack into a local variable.
+        action.addParameter(
+            n.getAntecedentState(), 
+            n.getAntecedentState(), 
+            ParameterDescriptor.ArityType.Fixed
+        );
+
+        n.setReduceAction(action);
+    }
+
+    /**
+     *  If this simple transformation is not yet known, add it to its rule table.
+     */
+    private void addSimpleTransformationRule(AST transform)
+    {
+        JBurgRule newRule = new JBurgRule(transform);
+
+        String key = String.format("%s=%s", newRule.getGoalState(), newRule.getAntecedentState());
+
+        if ( ! this.simpleTransformationRules.containsKey(key) )
+        {
+            //  Ensure this rule's nonterminal is known.
+            this.allGoalStates.add(newRule.getGoalState());
+            addNamedRule(this.transformationRules, newRule);
+
+            //  Target-specific action logic will be
+            //  added once the code emitter is up.
+            this.simpleTransformationRules.put(key, newRule);
+        }
+    }
+
+    /**
+     *  Wrap a pattern rule in an I-node, and add it to pattern rule table.
+     */
+    private void addPatternRule(AST newRule) throws Exception
+    {
+        JBurgRule n = addNamedRule(this.patternRules, newRule);
+
+        JBurgReduceAction newAction = decodeReduction(newRule, n.getGoalState());
+
+        n.setReduceAction(newAction);
+    }
+
+    /**
+     *  Wrap a rule in an I-node, and add it to the list of rules
+     *  that produce a particular subgoal.
+     */
+    private JBurgRule addNamedRule(Map<String, Vector<JBurgRule>> ruleTable, AST newAST)
+    {
+        JBurgRule newRule = new JBurgRule(newAST);
+
+        //  Ensure this rule's nonterminal is known.
+        this.allGoalStates.add( newRule.getGoalState() );
+        return addNamedRule(ruleTable, newRule);
+    }
+
+    /**
+     *  Add a rule to its rule table.
+     *  @param ruleTable - the appropriate table for this type of rule.  Keyed by operator.
+     *  @param newRule - the rule to add.
+     */
+    private JBurgRule addNamedRule(Map<String, Vector<JBurgRule>> ruleTable, JBurgRule newRule)
+    {
+        //  Store the rule by operator.
+        String operator = newRule.getOperator();
+
+        Vector<JBurgRule> vRules = ruleTable.get(operator);
+
+        if (vRules == null)
+        {
+            vRules = new Vector<JBurgRule>();
+            ruleTable.put(operator, vRules);
+        }
+
+        vRules.add(newRule);
+
+        return newRule;
+    }
+
+    /**
+     *  Compute the closure set of a rule:  the set of rules that
+     *  that can transform this rule's goal to satsify another goal.
+	 *  @note computeClosure is public so that it can be applied
+	 *    by JBurgUtilities.
+     */
+    public void computeClosure(JBurgRule n) throws Exception
+    {
+		//  Get the list of transformation rules that can use this rule's goal state.
+        Vector<JBurgRule> vClosureCandidate = this.transformationRules.get(n.getGoalState());
+
+        if (vClosureCandidate != null) 
+		{
+            //  Found some closures:
+            //  create or fetch this target state's closure set.
+            Vector<ClosureRecord> vClosureSet = this.closureSets.get(n.getGoalState());
+
+            if (vClosureSet == null) 
+			{
+                vClosureSet = new Vector<ClosureRecord>();
+                this.closureSets.put(n.getGoalState(), vClosureSet);
+            }
+
+            for (JBurgRule nPrime:vClosureCandidate ) 
+			{
+
+                //  Add this closure to the closure set.
+                ClosureRecord newClosure = new ClosureRecord(nPrime);
+
+                if (!vClosureSet.contains(newClosure)) 
+				{
+                    vClosureSet.add(newClosure);
+                }
+            }
+        }
+    }
+
+    /**
+     *  Scan all the rules and compute their closure sets.
+     */
+    private void computeClosureSets() throws Exception
+    {
+        for (Vector<JBurgRule> patterns : this.patternRules.values() ) 
+		{
+            try 
+			{
+                JBurgUtilities.applyToAll( this, patterns, "computeClosure", JBurgRule.class);
+            }
+			catch (Exception e)
+			{
+                e.printStackTrace();
+            }
+        }
+
+        for (Vector<JBurgRule> transformations : this.transformationRules.values() )
+		{
+            try
+			{
+                JBurgUtilities.applyToAll( this, transformations, "computeClosure", JBurgRule.class);
+            }
+			catch (Exception e)
+			{
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     *  Emit the BURG specification's resultant BURM to an output stream.
+     */
+    public int generate(String className, PrintStream output)
+    {
+        try
+		{
+            codeEmitter.setOpcodeType(this.opcodeType);
+        	emitHeader(className, output);
+        	codeEmitter.emitInclass(iNodeClass, this.inclassCode, output);
+
+        	emitNTConstants(this.allGoalStates, output);
+            emitStatics(output);
+
+			if ( this.iNodeAdapter instanceof InodeAuxiliarySupport )
+			{
+				((InodeAuxiliarySupport)this.iNodeAdapter).emitAuxiliarySupport(codeEmitter, output);
+			}
+
+            emitLabelFunction(this.iNodeClass, output);
+            ruleSemanticAnalysis();
+
+            if  ( codeEmitter.supportsSpecializedAnnotations() )
+            {
+                for (Vector<JBurgRule> vPatternRules: this.patternRules.values())
+                    this.compressedAnnotations.addAll(vPatternRules);
+            }
+            else
+            {
+                emitComputeCostMatrixFunction(this.iNodeClass, output);
+                emitClosures(this.closureSets, this.iNodeClass, output);
+            }
+            emitActions(this.reduceActions, this.iNodeClass, output);
+            emitCostFunctions(this.costFunctions, this.iNodeClass, output);
+
+            if ( codeEmitter.supportsSpecializedAnnotations() )
+                emitCompressedAnnotations(output);
+            
+            //  If there's an InodeAdapter2 present,
+            //  emit the getNthChild routine that
+            //  implements the adapter's node-handling logic.
+            if ( this.adapter2 != null)
+                emitGetNthChild(output);
+
+            codeEmitter.emitTrailer(
+				className,
+				this.iNodeClass,
+				this.allGoalStates,
+				this.burmProperties,
+				this.debugMode,
+                this.defaultErrorHandler,
+                this.prologueBlocks,
+				output
+			);
+        }
+		catch (Exception e)
+		{
+            e.printStackTrace();
+			this.errCount++;
+        }
+
+		return this.errCount;
+    }
+
+    //  Emit static lookup tables.
+    private void emitStatics(PrintStream output)
+    {
+        //  Emit the static table of subgoal records.
+        Map<Integer, Vector<JBurgPatternMatcher>> rules_by_action = new HashMap<Integer,Vector<JBurgPatternMatcher>>();
+        int max_action = 0;
+        for (Vector<JBurgRule> vPatternRules: patternRules.values())
+        {
+            for (JBurgRule p: vPatternRules)
+            {
+                int action_number = p.getReduceAction().getIndex();
+                max_action = Math.max(max_action, action_number);
+                
+                if ( p.patternMatcher.isNary() )
+                {
+                    rules_by_action.put(action_number,new Vector<JBurgPatternMatcher>());
+                    rules_by_action.get(action_number).add(p.patternMatcher);
+                }
+                else if (!p.patternMatcher.getParameterizedSubtrees().isEmpty() )
+
+                {
+                    rules_by_action.put(action_number,p.patternMatcher.getParameterizedSubtrees());
+                }
+            }
+        }
+
+        //  Ensure the transformation rules' actions have subgoal records.
+        for ( Vector<JBurgRule> transformations:  this.transformationRules.values() )
+            for ( JBurgRule t: transformations )
+                max_action = Math.max(max_action, t.getReduceAction().getIndex());
+        
+        codeEmitter.emitStatics(max_action, rules_by_action, output);
+
+        //  Generate manifest constant declarations.
+        for ( Map.Entry<String,Integer> constants : this.manifestConstants.entrySet() )
+            genInstanceField(
+                output,
+                Modifier.PUBLIC + Modifier.STATIC + Modifier.FINAL,
+                "int",
+                constants.getKey(),
+                constants.getValue().toString()
+            );
+    }
+
+    /**
+     *  Get the payload of an identifier, with error checking.
+     *  @return the identifier's text.
+     */
+    private String getIdentifierText(AST p)
+    {
+		if ( p.getType() != IDENTIFIER )
+		{
+			throw new IllegalStateException ( "Expected IDENTIFIER, found " + p.toStringTree() );
+		}
+
+        return p.getText();
+    }
+
+    /**
+     *  Does this production have a closure set?
+     *  @return true if n has a closure set.
+     *  @param n - the production of interest.
+     */
+    public boolean hasClosure(JBurgProduction n)
+    {
+        return this.closureSets.get(n.getGoalState()) != null;
+    }
+
+    /**
+      *  Emit the file/class header information.
+      */
+    private void emitHeader(String className, PrintStream output)
+    {
+        genComment(output, " Generated " + new java.util.Date().toString() + " by JBurg version " + JBurgVersion.version  );
+        output.println();
+        
+        codeEmitter.emitHeader(className, this.packageName, this.headerBlock, this.interfaceNames, this.debugMode, output);
+    }
+
+	/**
+	 *  @return the return type for a specific state.
+	 */
+	public String getReturnType(String stateName)
+	{
+		Object result = returnTypeTable.get(stateName);
+
+		if (result == null)
+			result = defaultReturnType;
+
+		return result.toString();
+	}
+	
+    /**
+     *  setDebugMode controls the level of debugging code that will be generated in the reducer.
+     */
+    public void setDebugMode(boolean bDebugMode)
+    {
+        debugMode = bDebugMode;
+    }
+    
+	/**
+	 *  @return the text of the parent AST's code block, which is represented as a BLOCK token.
+	 */
+	private String getCodeBlock( AST parent )
+	{
+		return getASTByType(parent, BLOCK).getText();
+	}
+
+    /**
+     *  @return the first child of the parent AST with the specified node type.
+     */
+    private AST getASTByType(AST parent, int node_type)
+    {
+        for ( AST current = parent.getFirstChild(); current != null; current = current.getNextSibling() )
+        {
+            if ( current.getType() == node_type )
+                return current;
+        }
+
+        throw new IllegalStateException ( "AST " + parent.toString() + " has no child of node type " + node_type + "." );
+    }
+
+    private boolean hasASTOfType(AST parent, int node_type)
+    {
+        for ( AST current = parent.getFirstChild(); current != null; current = current.getNextSibling() )
+        {
+            if ( current.getType() == node_type )
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     *  A JBurgProduction is a view of a pattern-matching rule (JBurgRule) 
+     *  or a nonterminal transformation rule (ClosureRecord) that exposes
+     *  characteristics important in their static analysis.
+     */
+    public interface JBurgProduction
+    {
+        /**
+         *  @return the nonterminal this production produces.
+         */
+        public String getGoalState();
+
+        /**
+         *  @return the code snippet that computes
+         *    or retrieves this production's 
+         *    (potentially) cached code.
+         */
+        public String getCachedCost();
+
+        /**
+         *  @return this production's reduce action.
+         */
+        public JBurgReduceAction getReduceAction();
+
+        /**
+         *  Is this production's cost constant in the
+         *  context where it's to be invoked?
+         *  @param productions - the set of productions at the
+         *    point where this productions's cost is required.
+         */
+        public boolean computesConstantCost(Multimap<String, JBurgProduction> productions);
+
+        /**
+         *  Get the constant cost of a production.
+         *  @param productions - the set of productions at the
+         *    point where this production's cost is required.
+         *  @return the cost, with overflow-safe addition.
+         *  @pre computesConstantCost(productions) must be true.
+         */
+        public int getConstantCost(Multimap<String, JBurgProduction> productions);
+    }
+
+    /**
+     *  JBurgRule contains an AST that represents a rule, 
+     *  its associated JBurgReduceAction,
+     *  and accessors to the AST's components.
+     */
+    public class JBurgRule implements JBurgProduction
+    {
+        /**
+         *  The parsed rule.
+         */
+        AST m_AST;
+        
+        /**
+         *  If the rule is a pattern rule, its pattern matcher.
+         */
+        JBurgPatternMatcher patternMatcher = null;
+        
+        /**
+         * The rule's reduction action.
+         */
+        JBurgReduceAction reduceAction;
+
+        /**
+         *   The pattern as a String; precomputed so it can be used as a key
+         *   to group labeling choices by common patterns.
+         */
+        private String encodedPattern;
+
+        public JBurgRule(AST n)
+        {
+            m_AST = n;
+            
+            if ( m_AST.getType() == PATTERN_RULE )
+            {
+                AST pattern_root = m_AST.getFirstChild().getNextSibling().getFirstChild();
+                try
+                {
+                    this.patternMatcher = generateMatcher(pattern_root); 
+                }
+                catch ( Exception ex )
+                {
+                    logger.exception("Building pattern recognizer for " + m_AST.toStringTree(), ex);
+                }
+            }
+        }
+
+        String getEncodedPattern()
+        {
+            if ( this.encodedPattern == null )
+            {
+                this.encodedPattern = 
+                    patternMatcher.generatePatternRecognizer(
+                        codeEmitter,
+                        "node",
+                        JBurgGenerator.this.adapter2
+                    );
+            }
+            
+            if ( this.encodedPattern == null )
+                this.encodedPattern = nilPattern;
+
+            return this.encodedPattern;
+        }
+
+        /**
+         * @param baseNode - the path to the base of the subtree.
+         * @return the subtree's cost specification.
+         */
+        public String getCost(String baseNode)
+        {
+            if ( m_AST.getType() != SIMPLE_TRANSFORMATION_RULE )
+            {
+                AST cost_spec = m_AST.getFirstChild().getNextSibling()
+                        .getNextSibling();
+
+                String costText = cost_spec.getFirstChild().getText();
+
+                if ( hasCostFunction() )
+                    return genCallMethod(null, costText, baseNode);
+                else
+                    return costText;
+            }
+            else
+            {
+                // Simple transformation rules don't cost anything.
+                return "0";
+            }
+        }
+        
+        /** 
+         *  @return true if the rule has a constant cost.
+         */
+        public boolean hasConstantCost()
+        {
+            if ( m_AST.getType() != SIMPLE_TRANSFORMATION_RULE )
+            {
+                AST cost_spec = m_AST.getFirstChild().getNextSibling()
+                        .getNextSibling();
+
+                String costText = cost_spec.getFirstChild().getText();
+
+                boolean ownCostConstant =
+                    cost_spec.getType() == LITERAL_COST_SPEC ||
+                    JBurgGenerator.this.manifestConstants.containsKey(costText);
+                
+                return ownCostConstant &&
+                     (this.isTerminalPattern() || this.patternMatcher == null);
+            }
+            else
+            {
+                // Simple transformation rules all cost 0.
+                return true;
+            }
+        }
+        
+        /**
+         *  @return the rule's cost.
+         *  @throws IllegalStateException if the cost isn't constant.
+         */
+        public Integer getConstantCost()
+        {
+            if ( m_AST.getType() != SIMPLE_TRANSFORMATION_RULE )
+            {
+                AST cost_spec = m_AST.getFirstChild().getNextSibling()
+                        .getNextSibling();
+
+                String costText = cost_spec.getFirstChild().getText();
+
+                if ( cost_spec.getType() == LITERAL_COST_SPEC )
+                {
+                    return new Integer(costText);
+                }
+                else if ( JBurgGenerator.this.manifestConstants.containsKey(costText) )
+                {
+                    return JBurgGenerator.this.manifestConstants.get(costText);
+                }
+                else
+                {
+                    throw new IllegalStateException("non constant cost: " + costText);
+                }
+            }
+            else
+            {
+                // Simple transformation rules don't cost anything.
+                return 0;
+            }
+        }
+
+        /**
+         *  @return true if the cost specification is a function call.
+         */
+        public boolean hasCostFunction()
+        {
+            boolean result = false;
+
+            if ( m_AST.getType() != SIMPLE_TRANSFORMATION_RULE )
+                result = m_AST.getFirstChild().getNextSibling().getNextSibling().getType() == FUNCTION_CALL;
+
+            return result;
+        }
+
+        /**
+         *  @return the rule's cached cost.
+         */
+        @Override
+        public String getCachedCost()
+        {
+            if ( this.hasCostFunction() )
+                return String.format("cachedCost_%h()", getCost(reducerNodeName));
+            else
+                return getCost(reducerNodeName);
+
+        }
+
+        /**
+         *  @return the rule's reduction action.
+         */
+        @Override
+        public JBurgReduceAction getReduceAction()
+        {
+			if ( null == this.reduceAction )
+			{
+				throw new IllegalStateException( "getReduceAction() has no action to return." );
+			}
+
+            return this.reduceAction;
+        }
+
+        /**
+         *  @return the antecedent state of a nonterminal-to-nonterminal
+         *    reduction, i.e., the state that the subtree must be reduced
+         *    to before this reduction can run.
+         */
+        public String getAntecedentState()
+        {
+             if ( m_AST.getType() == SIMPLE_TRANSFORMATION_RULE )
+             {
+                 return m_AST.getFirstChild().getNextSibling().getText();
+             }
+             else if ( m_AST.getType() == TRANSFORMATION_RULE )
+             {
+                 return m_AST.getFirstChild().getNextSibling().getText();
+             }
+             else
+                 throw new IllegalStateException(String.format("no antecedent for %s", m_AST.getType()));
+        }
+
+        /**
+         *  @return the node ID of the node at the root of the subtree.
+         */
+        public String getOperator()
+        {
+			int type = m_AST.getType();
+
+			if ( PATTERN_RULE == type )
+			{
+				return m_AST.getFirstChild().getNextSibling().getFirstChild().getFirstChild().getText();
+			}
+			else
+			{
+			    //  A transformation rule.
+				return m_AST.getFirstChild().getNextSibling().getText();
+			}
+        }
+
+        /**
+         *  @return the nonterminal produced by this reduction.
+         */
+        @Override
+        public String getGoalState()
+        {
+            return m_AST.getFirstChild().getText();
+        }
+
+        /**
+         *  Set this rule's associated action code.
+         */
+        public void setReduceAction(JBurgReduceAction reduceAction)
+        {
+            this.reduceAction = reduceAction;
+        }
+
+        /**
+         *  @return true if this node has no children (a "leaf" node).
+         */
+        public boolean isTerminalPattern()
+        {
+            return this.isFixedArity() && this.patternMatcher.getNominalArity() == 0;
+        }
+
+        /**
+         *  @return true if this rule's pattern has a fixed number of "operand" subtrees.
+         */
+        public boolean isFixedArity()
+        {
+            return this.patternMatcher != null && !this.patternMatcher.hasNaryTail();
+        }
+
+        /**
+         *  @return true if this rule needs an out-of-line method to check its cost.
+         */
+        public boolean needsCostFunction()
+        {
+            if ( this.isTerminalPattern() )
+                return false;
+            else if ( this.patternMatcher.hasNaryTail() )
+                return  this.patternMatcher.getNominalArity() != this.patternMatcher.getMinimumNaryChildCount();
+            else
+                return true;
+        }
+
+        /**
+         *  Is this production's cost constant in the
+         *  context where it's to be invoked?
+         *  @param productions - the set of productions at the
+         *    point where this productions's cost is required.
+         */
+        @Override
+        public boolean computesConstantCost(Multimap<String, JBurgProduction> productions)
+        {
+            return hasConstantCost();
+        }
+
+        /**
+         *  Get the constant cost of a production.
+         *  @param productions - the set of productions at the
+         *    point where this production's cost is required.
+         *  @return the cost, with overflow-safe addition.
+         *  @pre computesConstantCost(productions) must be true.
+         */
+        @Override
+        public int getConstantCost(Multimap<String, JBurgProduction> productions)
+        {
+            return getConstantCost();
+        }
+
+        @Override
+        public String toString()
+        {
+            return m_AST.toStringTree();
+        }
+    }
+
+    /**
+     *  JBurgReduceAction holds action code fragments and their associated "parameters."
+     *  A rule specifies "parameters" by naming individual subgoal states within a pattern
+     *  rule specifiction, for example,
+     *  <xmp>integer = PLUS ( integer i1, integer i2 )</xmp>
+     *  In this example, i1 and i2 are the action routine's "parameters."  Since the action
+     *  routines all share a common signature, the parameters are passed via the reducer's
+     *  reduced values stack.
+     */
+    private class JBurgReduceAction
+    {
+        /** The routine's source, from the input specification. */
+        private String actionCode;
+        
+        /**
+         * The non-terminal state produced by this action, e.g., expression from
+         * <xmp>expression = ADD(expression l, expression r)</xmp>
+         */
+        private String m_state;
+
+        /**
+         *  The antecedent reduction of a nonterminal-to-nonterminal rule.
+         */
+        private String antecedentState;
+        
+        /**
+         *  The operator ID of a pattern rule; used to find content-handling
+         *  code from the InodeAdapter2.
+         */
+        private String m_operator;
+        
+        /**
+         * Names and types of the routine's parameters.
+         * Types are given as their non-terminal state names; toString()
+         * translates these BURM-centric types into the corresponding
+         * types in the target language using the mapping set up by
+         * the ReturnType directives in the input specification.
+         */
+        private Vector<ParameterDescriptor> m_parameterList = new Vector<ParameterDescriptor>();
+
+        /**
+         *  This action routine's index, assigned in entry order.
+         *  The action routines are enumerated as action_1(JBurgNode p), action_2(JBurgNode p),
+         *  etc. in the generated reducer.
+         */
+        int index;
+        
+        /**
+         * Track name-to-subtree mappings to be emitted.
+         */
+        class NamedSubtree
+        {
+            String path;
+            String name;
+            
+            NamedSubtree(String path, String name)
+            {
+                this.path = path;
+                this.name = name;
+            }
+        }
+        /**
+         *  Saved name-to-subtree mappings.
+         */
+        Vector<NamedSubtree> namedChildNodes = new Vector<NamedSubtree>();
+        
+        /**
+         * Construct a reduce action.
+         * @param strActionCode - the action's implementation
+         * code, in a target-specific language 
+         */
+        public JBurgReduceAction(String strActionCode)
+        {
+            this.actionCode = strActionCode;
+        }
+
+        /**
+         * Add a parameter to the action's parameter list.
+         */
+        public void addParameter(String parmName, String parmState, ParameterDescriptor.ArityType arityType)
+            throws Exception
+        {
+            m_parameterList.add(new ParameterDescriptor(parmName, parmState, arityType));
+        }
+
+        /**
+         *  Return this action's index (the N constituent of its generated name, action_N).
+         */
+        public int getIndex()
+        {
+            return this.index;
+        }
+
+        /**
+         *  Set this action's index (the N constituent of its generated name, action_N).
+         */
+        public void setIndex(int index)
+        {
+            this.index = index;
+        }
+
+        /**
+         * Set the non-terminal state this reduction derives.
+         * @param state - the non-terminal state, e.g., expression from
+         * <xmp>expression = ADD(expression l, expression r)</xmp>
+         */
+        public void setState(String state)
+        {
+            this.m_state = state;
+        }
+
+        /**
+         * @return the non-terminal state this reduction derives.
+         */
+        public String getState()
+        {
+            return this.m_state;
+        }
+
+        /**
+         *  @param operator the operator at the root of 
+         *    the matched subtree.
+         */
+        public void setOperator(String operator)
+        {
+            this.m_operator = operator;
+        }
+
+        /**
+         * @return the operator at the root of 
+         *    the matched subtree.
+         */
+        public String getOperator()
+        {
+            return m_operator;
+        }
+
+        /**
+         *  Return the reduction action's code, 
+         *  with prepended logic to pop its parameters off the stack.
+         */
+        @Override
+        public String toString()
+        {
+            String result = "";
+
+            for ( ParameterDescriptor next_param: m_parameterList )
+            {
+                String paramName = next_param.paramName;
+                String paramType = getReturnType(next_param.paramState);
+
+				if ( next_param.arityType == ParameterDescriptor.ArityType.Variable )
+				{
+					paramType = codeEmitter.genNaryContainerType(paramType);
+				}
+                
+                result += codeEmitter.genActionRoutineParameter(reducedValuesName, paramType, paramName);
+            }
+            
+            for ( NamedSubtree named_child: this.namedChildNodes )
+            {
+                result += "\n\t" + iNodeClass + " " + named_child.name + " = " + named_child.path + ";";
+            }
+
+            // insert 2 tabs into each line, and convert \r\n to \n so the generated
+			// files have consistent line endings.
+			String[] actionlines = this.actionCode.toString().split("\n");
+			for( int l = 0; l < actionlines.length; ++l )
+			{
+				if(actionlines[l].endsWith("\r"))
+				{
+					actionlines[l] = actionlines[l].substring(0,actionlines[l].length()-1);
+				}
+				result += "\n\t\t" + actionlines[l];
+			}
+
+			return result;
+        }
+
+        /**
+         *  Track a name-to-subtree mapping.  These are unreduced I-nodes,
+         *  typically a terminal identified by pattern match.
+         *  @param path - the path from the root node to the subtree.
+         *  @param name - the name to give to the subtree.
+         */
+        public void addNamedSubtree(String path, String name)
+        {
+            namedChildNodes.add(new NamedSubtree(path, name));
+        }
+
+        /**
+         *  Set this reduction's antecedent state, which
+         *  determines what reduction needs to run before
+         *  this one to transform one nonterminal to another.
+         */
+        public void setAntecedentState(String antecedentState)
+        {
+            this.antecedentState = antecedentState;
+        }
+
+        /**
+         *  @return true if this rule has an antecedent state,
+         *    which also means it's a nonterminal-to-nonterminal rule.
+         */
+        public boolean hasAntecedentState()
+        {
+            return getAntecedentState() != null;
+        }
+
+        /**
+         *  @return this rule's antecedent state,
+         *    or null if no antecedent is present.
+         */
+        public String getAntecedentState()
+        {
+            return this.antecedentState;
+        }
+    }
+
+    /**
+     *  ClosureRecord tracks the target state, cost, and action code associated
+     *  with a reduction from an antecedent nonterminal to a target nonterminal state.
+     */
+    private class ClosureRecord implements JBurgProduction
+    {
+        private JBurgRule rule;
+
+        public ClosureRecord(JBurgRule rule) throws Exception
+        {
+            this.rule = rule;
+        }
+
+        /**
+         *  Get the closure's uncached cost.
+         *  @deprecated Will be removed when rules start caching costs.
+         */
+        public String getCost(String baseNT)
+        {
+            return this.rule.getCost(baseNT);
+        }
+
+        /**
+         *  Get the closure's (potentially) cached cost.
+         */
+        @Override
+        public String getCachedCost()
+        {
+            String cost = this.rule.getCost(reducerNodeName);
+
+            //  The cost function result will be cached;
+            //  return a unique accessor method name.
+            if ( hasCostFunction() )
+                return genCallMethod(null, String.format("getCostFunctionResult_%h", cost));
+            else
+                return cost;
+        }
+
+        /**
+         *  @return the rule's hasCostFunction() result.
+         */
+        public boolean hasCostFunction()
+        {
+            return rule.hasCostFunction();
+        }
+
+        /**
+         *  @return the rule's getConstantCost() result.
+         */
+        public int getConstantCost()
+        {
+            return this.rule.getConstantCost();
+        }
+
+        /**
+         *  @return the rule's hasConstantCost() result.
+         */
+        public boolean hasConstantCost()
+        {
+            return this.rule.hasConstantCost();
+        }
+
+        /**
+         *  @return the rule's getAntecedentState() result.
+         */
+        public String getAntecedentState()
+        {
+            return this.rule.getAntecedentState();
+        }
+
+        /**
+         *  @return the rule's getGoalState() result.
+         */
+        @Override
+        public String getGoalState()
+        {
+            return this.rule.getGoalState();
+        }
+
+        /**
+         *  @return this closure's reduce action.
+         */
+        @Override
+        public JBurgReduceAction getReduceAction()
+        {
+            return rule.getReduceAction();
+        }
+
+        /**
+         *  Closure records are equal if they have the same goal state, action, and cost.
+         *  @see java.lang.Object#equals
+         *
+         * @param o -- the object to test for equality.
+         * @return true if o is a ClosureRecord and it equals this one.
+         *
+         */
+        @Override
+        public boolean equals(Object o)
+        {
+            boolean result = false;
+
+            if (o instanceof ClosureRecord)
+            {
+                ClosureRecord cuz = (ClosureRecord) o;
+
+                result = getGoalState().equals(cuz.getGoalState());
+                result &= getReduceAction().equals(cuz.getReduceAction());
+                result &= this.rule.getCost(reducerNodeName).equals(cuz.rule.getCost(reducerNodeName));
+            }
+
+            return result;
+        }
+
+        /**
+         *  @return true if the cost of this closure is known to be zero.
+         */
+        public boolean costIsZero()
+        {
+            return hasConstantCost() && getConstantCost() == 0;
+        }
+
+        /**
+         *  @return the computation of this closure's cost,
+         *    which is somewhat error-prone when open coded.
+         */
+        public String getCostComputation()
+        {
+            String antecedentCost = 
+                genCallMethod(
+                    null,
+                    "getCost",
+                    getNonterminal(this.getAntecedentState())
+                );
+
+            if ( this.costIsZero() )
+            {
+                return antecedentCost;
+            }
+            else
+                return codeEmitter.genOverflowSafeAdd(this.getCachedCost(), antecedentCost);
+        }
+
+        /**
+         *  Precompute the cost of this closure if possible.
+         *  @param productions - the set of productions at the
+         *    point where the closure's cost is required.  If
+         *    the closure derives a single pattern-match 
+         *    rule that has a constant cost, and the closure
+         *    itself has a constant cost, then the cost
+         *    can be precomputed.
+         *  @return the precomputed cost, or the result of
+         *    calling {@link getCostComputation()} to get
+         *    a non-constant cost.
+         */
+        public String getCostComputation(Multimap<String, JBurgProduction> productions)
+        {
+            //  A closure back to a pattern-match with constant cost can be precomputed.
+            if ( this.computesConstantCost(productions) )
+            {
+                return Integer.toString(getConstantCost(productions));
+            }
+            else
+            {
+                //  Return the naive cost computation.
+                return getCostComputation();
+            }
+        }
+
+        /**
+         *  Get the constant cost of a closure.
+         *  @param productions - the set of productions at the
+         *    point where the closure's cost is required.
+         *  @return the cost, with overflow-safe addition.
+         *  @pre computesConstantCost(productions) must be true.
+         */
+        @Override
+        public int getConstantCost(Multimap<String, JBurgProduction> productions)
+        {
+            long constantAntecedent;
+            JBurgProduction production = productions.get(this.getAntecedentState()).get(0);
+
+            if ( production instanceof JBurgRule )
+                constantAntecedent = ((JBurgRule)production).getConstantCost();
+            else
+                constantAntecedent = ((ClosureRecord)production).getConstantCost(productions);
+
+            //  Integer-overflow safe addition.
+            @SuppressWarnings("cast")
+            long accum = (long)this.getConstantCost() + constantAntecedent;
+
+            if ( accum < Integer.MAX_VALUE )
+                return (int) accum;
+            else
+                return Integer.MAX_VALUE;
+        }
+
+        /**
+         *  Does this closure compute a constant cost
+         *  in the context of the given productions?
+         *  @param productions - the set of productions at the
+         *    point where the closure's cost is required.  If
+         *    the closure derives a single pattern-match 
+         *    rule that has a constant cost, and the closure
+         *    itself has a constant cost, then the cost
+         *    can be precomputed.
+         *  @return true if the computed cost is constant.
+         */
+        @Override
+        public boolean computesConstantCost(Multimap<String, JBurgProduction> productions)
+        {
+            boolean result = false;
+            if ( this.hasConstantCost() )
+            {
+                ArrayList<JBurgProduction> antecedents = productions.get(this.getAntecedentState());
+
+                if ( antecedents.size() == 1 )
+                {
+                    JBurgProduction production = antecedents.get(0);
+
+                    if ( production instanceof JBurgRule )
+                        result = ((JBurgRule)production).hasConstantCost();
+                    else
+                        result = ((ClosureRecord)production).computesConstantCost(productions);
+                }
+            }
+
+            return result;
+        }
+
+    }
+
+	/**
+	 *  A ParameterDescriptor is a pair (name, subgoalState) which parallels
+	 *  the FOO(name, subgoalState) found in the specification's syntax.
+	 */
+    private static class ParameterDescriptor
+    {
+        String paramName;
+        String paramState;
+        ArityType arityType;
+        
+        enum ArityType {Fixed, Variable}
+
+        ParameterDescriptor(String paramName, String paramState, ArityType arityType)
+        {
+            this.paramName = paramName;
+            this.paramState = paramState;
+            this.arityType = arityType;
+        }
+    }
+
+    /**
+     *  Finish semantic analysis of the pattern rules.
+     */
+	private void ruleSemanticAnalysis() throws Exception
+    {
+        for (Vector<JBurgRule> vPatternRules: this.patternRules.values())
+        {
+            for (JBurgRule rule: vPatternRules)
+            {
+                for (JBurgPatternMatcher subgoal: rule.patternMatcher.getParameterizedSubtrees())
+                {
+                    rule.getReduceAction().addParameter(
+                            subgoal.getParameterName(), 
+                            subgoal.getSubgoal(), 
+                            subgoal.isNary()? ParameterDescriptor.ArityType.Variable: ParameterDescriptor.ArityType.Fixed
+                            );
+                }
+
+                //  Add the named subtrees as a convenience.
+                for ( JBurgPatternMatcher named_terminal: rule.patternMatcher.getNamedSubtrees())
+                {
+                    rule.getReduceAction().addNamedSubtree(
+                            named_terminal.generateReduceTimePath(codeEmitter, reducerNodeName, this.iNodeAdapter, this.adapter2 != null), 
+                            named_terminal.getParameterName()
+                            );
+                }
+
+                //  If the pattern matches an operator, send that operator
+                //  to the rule so it can be matched in content-access snippets.
+                if ( rule.patternMatcher.matchesOperator() )
+                    rule.getReduceAction().setOperator(rule.patternMatcher.getOperator());
+            }
+        }
+    }
+
+	private void emitComputeCostMatrixFunction(String iNodeClass, PrintStream output) throws Exception 
+	{
+		//  Emit the method declaration and local variables.
+		genDeclareMethod( output, Modifier.PRIVATE, "void", "computeCostMatrix", "JBurgAnnotation", "node");
+		genBeginBlock(output);
+		genLocalVar(output,  "long", "iCost", null );
+
+		//  The calculations are based on finding patterns
+		//  that can label the node's type.
+		genSwitch(output, genCallMethod( "node", "getOperator" ));
+
+		//  Try each pattern for a match.
+		//  Any pattern that matches then checks its 
+		//  cost to see if it's less than the current
+		//  best cost for the node, and replaces the 
+		//  node's current rule and cost with its own
+		//  if it's the new best cost.
+
+		for (Vector<JBurgRule> vPatternRules: this.patternRules.values())
+		{
+            genCase( output, vPatternRules.firstElement().getOperator() );
+            
+            //  Group rules by the patterns they match.
+            Multimap<String, JBurgRule> rules_by_pattern = new Multimap<String, JBurgRule>();
+
+            for (JBurgRule rule: vPatternRules)
+            {
+                String encoded_pattern = rule.getEncodedPattern();
+                rules_by_pattern.addToSet(encoded_pattern, rule);
+            }
+
+            
+            for ( String encoded_pattern: rules_by_pattern.keySet() )
+            {
+                ArrayList<JBurgRule> current_rules = rules_by_pattern.get(encoded_pattern);
+
+                //  Emit the structural pattern match if it was not optimized out.
+                if ( !encoded_pattern.equals(nilPattern))
+                    genIf(output, encoded_pattern);
+                
+                //  Begin a block whether there was a test or not, to scope variables.
+                //  TODO: This will not work for a target that doesn't block-scope locals.
+                genBeginBlock(output);
+                
+                //  Find common path and cost subexpressions.
+                Multimap<JBurgPatternMatcher, JBurgPatternMatcher> aggregated_matchers = new Multimap<JBurgPatternMatcher, JBurgPatternMatcher>();
+                
+                Multimap<String, JBurgPatternMatcher> costs = new Multimap<String, JBurgPatternMatcher>();
+                
+                for ( JBurgRule rule: rules_by_pattern.get(encoded_pattern))
+                {
+                    for (JBurgPatternMatcher subgoal: rule.patternMatcher.getParameterizedSubtrees() )
+                    {
+                        subgoal.aggregatePaths(aggregated_matchers);
+                        costs.addToSet(subgoal.generateCost(codeEmitter, "node"), subgoal);
+                    }
+                }
+                
+                //  Factor out common paths.
+                int factored_path_count = 0;
+                for ( JBurgPatternMatcher key: aggregated_matchers.keySet())
+                {
+                    ArrayList<JBurgPatternMatcher> matchers = aggregated_matchers.get(key);
+                    
+                    if ( matchers.size() > aggregatePathThreshold  )
+                    {
+                        String factored_path_var = "factored_path_" + Integer.toString(++factored_path_count);
+                        genLocalVar(output, "JBurgAnnotation ", factored_path_var, key.generatePathToRoot(codeEmitter, "node"));
+                        
+                        for ( JBurgPatternMatcher matcher: matchers)
+                            matcher.factoredPath = factored_path_var;
+                        
+                    }
+                }
+                
+                //  Now that the paths have been factored, factor out common costs.
+                int factored_cost_count = 0;
+                
+                for (String key: costs.keySet() )
+                {
+                    if ( costs.get(key).size() > 1 )
+                    {
+                        String factored_cost_var = "factored_cost" + Integer.toString(++factored_cost_count);
+                        //  Regenerate the cost because it may now use factored path expressions.
+                        ArrayList<JBurgPatternMatcher> matchers = costs.get(key);
+                        genLocalVar(output, "int", factored_cost_var, matchers.get(0).generateCost(codeEmitter, "node"));
+                        for ( JBurgPatternMatcher subgoal: matchers)
+                        {
+                            subgoal.factoredCost = factored_cost_var;
+                        }
+                    }
+                }
+
+                //  Emit the cost checks and their labeling logic.
+                
+                int patternPosition = 0;
+
+                for ( JBurgRule rule: current_rules )
+                    emitPatternRule(rule, iNodeClass, output, patternPosition++ == 0);
+
+                genEndBlock(output);
+            }
+
+            genEndCase(output);
+		}
+
+		genEndSwitch(output);
+		genEndBlock(output);
+	}
+	
+	/**
+	 *  Emit a routine that inspects the operators found at compiler compile time,
+	 *  and emits code to get the corresponding node's Nth child.
+	 *  @param output - the current output stream.
+	 */
+	private void emitGetNthChild(PrintStream output)
+	{
+	    genDeclareMethod(
+            output,
+            Modifier.PRIVATE,
+            this.iNodeClass,
+            "getNthChild",
+	        genFormals(this.iNodeClass, "node", "int", "index"),
+            throwsNothing
+        );
+	    genBeginBlock(output);
+	    genLocalVar(output, this.iNodeClass, "result", null);
+	    
+	    genSwitch(output, this.iNodeAdapter.genGetOperator("node", this.codeEmitter));
+	    for ( String opcode: this.allOperators)
+	    {
+	        Integer choice_count = this.adapter2.getMaxNthChildChoice(opcode);
+	        if ( choice_count != null )
+	        {
+                genCase(output, opcode);
+	            genSwitch(output, "index");
+	            for ( int i = 0; i < choice_count; i++ )
+	            {
+	                genCase(output, Integer.toString(i));
+	                genAssignment(output, "result", this.adapter2.genGetNthChild(opcode, "node", i, codeEmitter));
+	                genEndCase(output);
+	                
+	            }
+                //  generate the default case for the index.
+                {
+                    genDefaultCase(output);
+                    genAssignment(output, "result", this.adapter2.genGetDefaultChild(opcode, "node", "index", codeEmitter));
+                    genEndCase(output);
+                }
+
+                genEndSwitch(output);
+	            genEndCase(output);
+	        }
+	        
+	    }
+        //  generate the default case for the opcode.
+        {
+            genDefaultCase(output);
+            genAssignment(output, "result", this.iNodeAdapter.genGetNthChild("node", "index", codeEmitter));
+            genEndCase(output);
+        }
+	    genEndSwitch(output);
+	    genReturnValue(output, "result");
+	    genEndBlock(output);
+	}
+
+	private void emitPatternRule(JBurgRule p, String iNodeClass, PrintStream output, boolean isFirstRule ) throws Exception
+	{
+	    genComment(output, "Try matching " + p.getOperator() + " ==> " + p.getGoalState());
+	    
+        /*
+		 *   Emit code to compute this rule's cost, which is the cost of the rule itself 
+		 *   and all the non-terminals associated with it; then emit a comparison with
+		 *   the current best cost.
+		 */
+		Vector<String> sub_costs = new Vector<String>();
+
+		//  Compute the basic cost of the pattern match.
+		sub_costs.add(
+		    p.getCost( 
+    			codeEmitter.genCast( 
+    				iNodeClass, 
+    				codeEmitter.genAccessMember("node", "m_node")
+    			)
+            )
+		);
+		
+	   //  Try and compute a constant cost.
+        Integer constant_cost = null;
+
+		if ( p.hasConstantCost() )
+		{
+		    constant_cost = p.getConstantCost();
+		}
+
+		
+		for ( JBurgPatternMatcher subgoal: p.patternMatcher.getParameterizedSubtrees() )
+		{
+		    String subgoal_cost = subgoal.generateCost(codeEmitter, "node");
+		    if ( subgoal_cost != null )
+		    {
+		        sub_costs.add(subgoal_cost);
+		        constant_cost = null;
+		    }
+		}
+		
+		String cost_factor;
+        boolean checkCostFactor = true;
+		
+		if ( constant_cost != null )
+		{
+		    cost_factor = constant_cost.toString();
+            checkCostFactor = constant_cost == Integer.MAX_VALUE;
+		}
+		else if ( sub_costs.size() == 1 )
+		{
+		    cost_factor = sub_costs.get(0);
+		}
+		else
+		{
+            //  Compute the cost using a long accumulator.
+		    cost_factor = "iCost";
+
+    		String match_cost = codeEmitter.genCast("long", sub_costs.get(0));
+        		
+            for ( int i = 1; i < sub_costs.size(); i++ )
+                match_cost = codeEmitter.genAddition(match_cost, codeEmitter.genCast("long", sub_costs.get(i)));
+    		
+    		genAssignment(output, "iCost", match_cost);
+		}
+
+        if ( !isFirstRule || checkCostFactor )
+        {
+            //  Does this pattern match cost less than the previously best match?
+            String getCostCall = genCallMethod ( "node", "getCost", codeEmitter.genGetGoalState(p) );
+            String costCheck = codeEmitter.genCmpLess( getCostCall, cost_factor );
+            genIf(output, costCheck );
+        }
+
+		output.print( codeEmitter.genBeginBlock() );
+
+		/*
+		 *   Emit code to handle a successful match.
+		 */
+
+		//  Reset the reduce-time rule to fire.
+        String strRule = String.valueOf(p.getReduceAction().getIndex());
+        
+        //  Now that the comparison has been done using long arithmetic,
+        //  iCost can be safely truncated to fit in an int.
+        if ( cost_factor.equals("iCost"))
+            cost_factor = codeEmitter.genCast("int", cost_factor);
+
+        genExpressionStmt(
+            output, 
+			codeEmitter.genCallMethod(
+				"node", 
+				"reset", 
+				new String[] { codeEmitter.genGetGoalState(p), cost_factor, strRule }
+			)
+		);
+
+        if (hasClosure(p))
+		{
+            genExpressionStmt(
+                output,
+				genCallMethod( 
+					null, 
+					"closure_" + p.getGoalState(),
+					"node", cost_factor
+				)
+			);
+        }
+
+        //  End the block begun by the cost comparison above.
+        genEndBlock(output);
+    }
+	
+	private JBurgPatternMatcher generateMatcher(AST pattern_root)
+	throws Exception
+	{   
+        JBurgPatternEncoder patternBURM = new JBurgPatternEncoder();
+
+        //  As we traverse the subtree, we may find parameterized subtrees,
+        //  for example, in ADD(expr lhs, expr rhs) lhs and rhs are paramterized
+        //  subtrees.  These subtrees play several parts in the computation of the
+        //  locally-optimal reduction:
+        //  -  They contribute to the rule's computed cost.
+        //  -  The reduction's action code may refer to these elements by name.
+        //  -  If the rule is of the form OP(nttype1 a [, nttype2 b]), then the rule
+        //     must enforce this reduce-time goal state on its subtrees' reductions.
+        patternBURM.setSubgoals(new Vector<JBurgPatternMatcher>());
+        
+        //  There may also be named terminals in the pattern;
+        //  as a convenience, record these so that they
+        //  can be used by name in the reduction.
+        patternBURM.setNamedterminals(new Vector<JBurgPatternMatcher>());
+        
+        patternBURM.setOperators(this.allOperators);
+
+        try
+        {
+            patternBURM.burm( pattern_root );
+        }
+        catch (IllegalStateException burm_error )
+        {
+            if ( this.patternMatcherDumpFile != null )
+            {
+                //  Dump the BURM's debugging info.
+                java.io.PrintWriter dumper = new java.io.PrintWriter(new java.io.FileWriter(patternMatcherDumpFile));
+                dumper.println ( "<?xml version=\"1.0\"?>");
+                dumper.println("<BurmDump date=\"" + new java.util.Date().toString() + "\">");
+                patternBURM.dump(dumper);
+                dumper.println("<AST>");
+                dumper.println("<![CDATA[");
+                dumper.println(pattern_root.toStringTree());
+                dumper.println("]]>");
+                dumper.println("</AST>");
+                dumper.println("</BurmDump>");
+                dumper.flush();
+                dumper.close();
+            }
+            
+            throw burm_error;
+        }
+        
+        JBurgPatternMatcher recognizer = (JBurgPatternMatcher) patternBURM.getResult();
+        recognizer.setParameterizedSubtrees(patternBURM.getSubgoals());
+        recognizer.setNamedSubtrees(patternBURM.getNamedterminals());
+        
+        return recognizer;
+	}
+
+	private void emitActions(ArrayList<JBurgReduceAction> reduceActions, String iNodeClass, PrintStream output)
+	{
+		int i = 1;
+
+		//  Print out the individual action routines.
+		for (JBurgReduceAction nextAction: reduceActions )
+		{
+            output.println();
+			genComment(output, nextAction.getState());
+			
+            //  Compute the type of the i-node.
+            String typeOfOperatorINode;
+			final String actionOperator = nextAction.getOperator();
+
+			if ( opcodeNodeTypes.containsKey(actionOperator) )
+			    typeOfOperatorINode = opcodeNodeTypes.get(actionOperator);
+			else
+			    typeOfOperatorINode = iNodeClass;
+
+			genDeclareMethod(
+                output,
+				Modifier.PRIVATE,
+				getReturnType(nextAction.getState()),
+				"action_" + String.valueOf(i++),
+				genFormals(typeOfOperatorINode, reducerNodeName),
+				throwsException
+			);
+				
+			genBeginBlock(output);
+
+			String action_routine = nextAction.toString();
+			
+			//  Replace #OPERATOR# with a content-access snippet.
+			if ( this.adapter2 != null && nextAction.getOperator() != null )
+			{
+			    String content_access = this.adapter2.genGetContent(nextAction.getOperator(), this.reducerNodeName, nextAction.getState(), codeEmitter);
+			    
+			    if ( content_access != null )
+			    {
+			        String content_pattern = "#" + nextAction.getOperator() + "#";
+			        action_routine = action_routine.replaceAll( content_pattern, content_access );
+			    }
+			}
+			//  Replace #goalstate with the name of the action's input node.
+			
+			String goalPattern = "#" + nextAction.getState();
+			action_routine = action_routine.replaceAll( goalPattern, this.reducerNodeName );
+			
+			output.print( action_routine );
+
+			genEndBlock(output);
+		}
+
+		//  Emit their common dispatch routine.
+		genDeclareMethod(
+            output,
+			Modifier.PRIVATE,
+			"void",
+			"dispatchAction",
+			genFormals("JBurgAnnotation", "___node", "int", "iRule"),
+			throwsException
+		);
+
+		genBeginBlock(output);
+
+        genLocalVar(
+            output,
+            iNodeClass,
+            this.reducerNodeName,
+            genCallMethod("___node", "getNode")
+        );
+
+		genSwitch(output, "iRule" );
+
+		//  Emit the dispatch case statement.
+		for (i = 1; i <= reduceActions.size(); i++)
+		{
+            JBurgReduceAction action = reduceActions.get(i-1);
+
+			genCase(output, String.valueOf(i));
+            {
+                //  If this is a nonterminal-to-nonterminal
+                //  transformation, run the antecedent
+                //  reduction action.
+                if ( action.hasAntecedentState() )
+                {
+                    genExpressionStmt(
+                        output,
+                        genCallMethod(
+                            "this",
+                            "reduceAntecedent",
+                            "___node", codeEmitter.genGetGoalState(action.getAntecedentState())
+                        )
+                    );
+                }
+
+                final String operatorName = action.getOperator();
+                final String nodeTypeForOperator =
+                    operatorName != null ? opcodeNodeTypes.get(operatorName) : null;
+                String nodeParameterString = reducerNodeName;
+                if (nodeTypeForOperator != null)
+                    nodeParameterString = codeEmitter.genCast(nodeTypeForOperator, nodeParameterString);
+                
+                genExpressionStmt(
+                    output,
+                    codeEmitter.genPushToStack(
+                        reducedValuesName,
+                        genCallMethod(
+                            "this",
+                            "action_" + String.valueOf(i),
+                            nodeParameterString
+                        )
+                    )
+                );
+            }
+			genEndCase(output);
+		}
+
+		genDefaultCase(output);
+        {
+            genThrow(output, "\"Unmatched reduce action \" + iRule" );
+        }
+        genEndBlock(output); // genEndCase() without unreachable break
+	    
+		genEndSwitch(output);
+		genEndBlock(output);
+	}
+
+	private void emitNTConstants(Set<String> goal_states, PrintStream output)
+	{
+		Iterator<String> keys = goal_states.iterator();
+
+		int nthConstant = 0;
+
+		output.print(codeEmitter.genBeginLine());
+		while (keys.hasNext())
+		{
+			nthConstant++;
+
+			String strNTName = codeEmitter.genGetGoalState(keys.next().toString() );
+
+            genInstanceField(
+                output, 
+                Modifier.PUBLIC + Modifier.STATIC + Modifier.FINAL,
+                "int",
+                strNTName,
+                String.valueOf(nthConstant)
+			);
+		}
+	
+        genInstanceField(
+            output,
+            Modifier.PUBLIC + Modifier.STATIC + Modifier.FINAL,
+            "int",
+            "nStates",
+            String.valueOf(nthConstant)
+		);
+	}
+
+	public void emitCostFunctions(ArrayList<AST> costFunctions, String iNodeClass, PrintStream output) 
+	{
+		String[][] costParms = genFormals( iNodeClass, reducerNodeName );
+
+		for (int i = 0; i < costFunctions.size(); i++)
+		{
+			AST currentNode = costFunctions.get(i);
+
+			String functionName = currentNode.getFirstChild().getText();
+
+			genDeclareMethod(output, Modifier.PRIVATE, "int", functionName, costParms, throwsNothing );
+			output.print( codeEmitter.genBeginLine() );
+			output.print( getCodeBlock(currentNode) );
+		}
+	}
+
+	public void emitClosures(Map<String, Vector<ClosureRecord>> closureSets, String iNodeClass, PrintStream output)
+	{
+        //  TODO: This method can be removed once the C++ target
+        //  has been updated to 1.9.0 style semantics.
+		for (String strClosureNT: closureSets.keySet())
+		{
+			genDeclareMethod(
+				output,
+                Modifier.PRIVATE,
+                "void",
+                "closure_" + strClosureNT,
+                genFormals("JBurgAnnotation", reducerNodeName, "long", "c"),
+                throwsNothing
+			);
+
+			genBeginBlock(output);
+
+			genLocalVar(output, "long", "iCost", null );
+
+			for (ClosureRecord newClosure: closureSets.get(strClosureNT) )
+			{
+				String strRule;
+
+				if (newClosure.getReduceAction() != null)
+					strRule = String.valueOf(newClosure.getReduceAction()
+													   .getIndex());
+				else
+					strRule = "0";
+
+				String closureCost = newClosure.getCost( codeEmitter.genAccessMember(reducerNodeName, "m_node"));
+
+				if (closureCost.equals("0") )
+				{
+					genAssignment( output, "iCost", "c");
+				}
+				else
+				{
+					genAssignment( output, "iCost",  codeEmitter.genAddition( "c", closureCost ));
+				}
+
+                genIf(
+                    output,
+                    codeEmitter.genCmpLess(
+                        genCallMethod (
+                            reducerNodeName,
+                            "getCost", 
+                            getNonterminal(newClosure.getGoalState())
+                        ),
+                        "iCost"
+					)
+				);
+				output.print( codeEmitter.genBeginBlock() );
+
+                genExpressionStmt(
+                    output,
+					codeEmitter.genCallMethod(
+						reducerNodeName,
+						"reset",
+						new String[] { getNonterminal(newClosure.getGoalState()), codeEmitter.genCast("int","iCost"), strRule }
+					)
+				);
+
+                genExpressionStmt(
+                    output,
+					codeEmitter.genCallMethod(
+						reducerNodeName,
+						"recordAntecedent",
+						new String[] { getNonterminal(newClosure.getGoalState() ), getNonterminal(strClosureNT ) }
+					)
+				);
+
+				if (hasClosure(newClosure))
+				{
+                    genExpressionStmt(
+                        output,
+						genCallMethod(
+							"this",
+							"closure_" + newClosure.getGoalState(),
+							reducerNodeName, "iCost"
+						)
+					);
+				}
+
+				genEndBlock(output);
+			}
+
+			genEndBlock(output);
+		}
+	}
+
+
+	public void emitLabelFunction(String iNodeClass, PrintStream output)
+	{
+        genDeclareMethod(
+            output,
+            Modifier.PUBLIC,
+            "JBurgAnnotation",
+            "label",  
+            genFormals(iNodeClass, JBurgGenerator.initalParamName),
+            throwsNothing
+		);
+
+		genBeginBlock(output);
+		genLocalVar (output,  "JBurgAnnotation", "result", codeEmitter.genNullPointer() );
+		genLocalVar (output,  "int", "i", null);
+		genLocalVar (output,  "int", "arity", null);
+
+        String nodeAlloc = null;
+
+        if ( codeEmitter.supportsSpecializedAnnotations() )
+        {
+			nodeAlloc = genCallMethod( "this", "getJBurgAnnotation", JBurgGenerator.initalParamName);
+        }
+        else
+        {
+			nodeAlloc = codeEmitter.genNewObject( "JBurgAnnotation", new String[] { JBurgGenerator.initalParamName, "nStates + 1" } );
+        }
+		genAssignment( output, "result", nodeAlloc );
+
+		//  Generate a loop over children that labels them,
+		//  and adds their labelled JBurgAnnotation nodes to the current node.
+		genAssignment(output, "arity", this.iNodeAdapter.genGetArity(JBurgGenerator.initalParamName, codeEmitter));	
+		genAssignment(output, "i", "0");
+
+		genLine(output, codeEmitter.genWhileLoop( codeEmitter.genCmpLess("arity", "i")));
+		genBeginBlock(output);
+        {
+            genExpressionStmt(
+                output,
+                genCallMethod(
+                    "result",
+                    "addChild",
+                    genCallLabel("i")
+                )
+            );
+            
+            genAssignment(output, "i", codeEmitter.genAddition("i", "1") );
+        }
+		genEndBlock(output); // while
+
+		//  Call the costing function.
+        if ( ! this.codeEmitter.supportsSpecializedAnnotations() )
+            genExpressionStmt(output, genCallMethod( "this", "computeCostMatrix", "result"));
+
+		genReturnValue(output, "result" );
+		genEndBlock(output);
+	}
+
+    /**
+     *  Emit the subclasses of JBurgAnnotation that encode data for specific pattern matches.
+     *  @param output - the destination output stream.
+     */
+    void emitCompressedAnnotations(PrintStream output)
+    {
+        //  Emit an annotation object for each equivalence class of rules.
+        for ( String operator: this.compressedAnnotations.getOperators() )
+            for ( ArrayList<JBurgRule> currentRules : this.compressedAnnotations.getRulesFor(operator) )
+                emitAnnotation(output, currentRules);
+
+        //  Emit getJBurgAnnotation
+        genDeclareMethod(
+            output,
+            Modifier.PUBLIC,
+            "JBurgAnnotation",
+            "getJBurgAnnotation",  
+            genFormals(iNodeClass, "node"),
+            throwsNothing
+        );
+
+        genBeginBlock(output);
+
+	    genSwitch(output, this.iNodeAdapter.genGetOperator("node", this.codeEmitter));
+
+        for ( String operator: compressedAnnotations.getOperators() )
+        {
+            genCase(output, operator);
+
+            for ( ArrayList<JBurgRule> rules : this.compressedAnnotations.getRulesFor(operator) )
+            {
+                int arity = getMinumumArity(rules);
+
+                if ( hasNaryness(rules) )
+                    genIf(output, String.format("%s >= %d", this.iNodeAdapter.genGetArity("node", codeEmitter), arity));
+                else
+                    genIf(output, String.format("%s == %d", this.iNodeAdapter.genGetArity("node", codeEmitter), arity));
+                indentNextLine();
+                genReturnValue(output, String.format("new %s(node)", getSpecializedClassName(rules)));
+            }
+
+            genEndCase(output);
+        }
+
+        genEndSwitch(output);
+        
+        genLine(output, "return new JBurgAnnotationGeneral(node, nStates+1);");
+        genEndBlock(output); // getJBurgAnnotation
+        
+    }
+
+    /**
+     *  Emit an annotation subclass.
+     *  @param output - the output stream.
+     *  @param currentRules - the set of rules that are this annotation's
+     *    domain.  The rules all have the same operator, but their arity
+     *    may differ if some of them are n-ary.
+     */
+    void emitAnnotation(PrintStream output, ArrayList<JBurgRule> currentRules )
+    {
+        int nominalArity = getMinumumArity(currentRules);
+
+        // The coalesced graph of closures for all the rules.
+        ClosureGraph closureCosts = new ClosureGraph();
+
+        //  Factored common subtrees of each pattern matcher.
+        //  TODO: These can be further coalesced by using the right comparator.
+        Multimap<JBurgPatternMatcher,JBurgPatternMatcher> commonSubtrees = new Multimap<JBurgPatternMatcher,JBurgPatternMatcher>();
+
+        //  Rules and closures by nonterminal.
+        Multimap<String, JBurgProduction> productions = new Multimap<String, JBurgProduction>();
+
+        //  Cached subtree costs.
+        Map<String, String> cachedCosts = new HashMap<String, String>();
+
+        //  Are all these rules fixed-arity?
+        //  If so, the annotation knows its arity a priori.
+        boolean fixedArity = !hasNaryness(currentRules);
+
+        /*
+         *  **  Semantic analysis  **
+         */
+        
+        //  Populate the closure graph and factor the pattern matchers.
+        for ( JBurgRule rule: currentRules)
+        {
+            productions.addToSet(rule.getGoalState(), rule);
+
+            closureCosts.addClosures(rule.getGoalState());
+
+            if ( fixedArity )
+                rule.patternMatcher.setFixedArityContext(true);
+
+            for ( JBurgPatternMatcher subgoal: rule.patternMatcher.getParameterizedSubtrees() )
+                subgoal.findFactors(commonSubtrees);
+
+            if ( rule.patternMatcher.getNominalArity() > 0 )
+            {
+                cachedCosts.put(rule.getGoalState(), String.format("cachedCostFor_%s", rule.getGoalState()));
+            }
+        }
+
+        //  Add the closures from the coalesced closure graph
+        //  to the set of productions.
+        for ( Map.Entry<String, ArrayList<ClosureRecord>> closures: closureCosts.entrySet() )
+        {
+            for ( ClosureRecord closure: closures.getValue() )
+                productions.addToSet(closures.getKey(), closure);
+        }
+
+        //  Emitting these variable declarations mutates the 
+        //  pattern matchers, so they can only be emitted once.
+        //  Capture the results so we can write it more than once.
+        Map<JBurgPatternMatcher,String> factored_variables = emitFactoredPathVariables(commonSubtrees);
+
+        /*
+         * Begin code-gen of the class.
+         */
+        output.println();
+        String annotationClass = getSpecializedClassName(currentRules);
+        
+        genLine(output, String.format("class %s extends JBurgSpecializedAnnotation", annotationClass));
+        genBeginBlock(output);
+
+        //  Emit a field for each child.
+        for ( int fieldIdx = 0; fieldIdx < nominalArity; fieldIdx++ )
+        {
+            genInstanceField( output, Modifier.PRIVATE, "JBurgAnnotation", String.format("subtree%d", fieldIdx), null);
+        }
+
+        if ( !fixedArity )
+        {
+            genInstanceField( 
+                output,
+                Modifier.PRIVATE,
+                codeEmitter.genNaryContainerType("JBurgAnnotation"),
+                "narySubtrees",
+                String.format("new %s()", codeEmitter.genNaryContainerType("JBurgAnnotation"))
+            );
+        }
+
+        // Emit the constructor.
+        //  TODO: The emitter needs a genConstructor() API.
+        genLine(output, String.format("%s(%s node)", annotationClass, this.iNodeClass));
+        genBeginBlock(output);
+        //  TODO: The emitter also needs a callSuperclassConstructor() API.
+        genLine(output, "super(node);");
+        genEndBlock(output);
+
+        for ( String cachedCostVar: cachedCosts.values() )
+        {
+            genInstanceField( output, Modifier.PRIVATE, "int", cachedCostVar, UNINITIALIZED);
+        }
+
+        /*
+         *  ** Emit getCost()  **
+         */
+        genDeclareMethod( output, Modifier.PUBLIC, "int", "getCost", "int", "goalState" );
+        genBeginBlock(output);
+
+        genSwitch(output, "goalState");
+
+        for ( Map.Entry<String, ArrayList<JBurgProduction>> productionsByNonterminal: productions.entrySet() )
+        {
+            genCase(output, getNonterminal(productionsByNonterminal.getKey()));
+
+            ArrayList<JBurgProduction> currentProductions = productionsByNonterminal.getValue();
+
+            //  Try to find the optimal production at compiler-compile time.
+            JBurgProduction optimalProduction = findOptimalProduction(currentProductions, productions);
+
+            if ( optimalProduction != null )
+            {
+                genReturnValue(output, Integer.toString(optimalProduction.getConstantCost(productions)));
+            }
+            else
+            {
+                final boolean hasMultipleProductions = currentProductions.size() > 1;
+                final boolean cacheCost = cachedCosts.containsKey(productionsByNonterminal.getKey());
+
+                boolean currentCostDeclared = false;
+
+                String bestCostVar;
+
+                if ( cacheCost )
+                {
+                    bestCostVar = cachedCosts.get(productionsByNonterminal.getKey());
+                    genIf ( output, codeEmitter.genCmpEquality(bestCostVar, UNINITIALIZED, true) );
+                    genBeginBlock(output);
+                }
+                else if ( hasMultipleProductions )
+                {
+                    //  Store the best cost in a local.
+                    bestCostVar = "bestCost";
+                    genLocalVar(output, "int", "bestCost");
+                }
+                else
+                {
+                    bestCostVar = codeEmitter.genMaxIntValue();
+                }
+
+                for ( int i = 0; i < currentProductions.size(); i++ )
+                {
+                    JBurgProduction production = currentProductions.get(i);
+                    String productionCost = getCostForProduction(production, productions);
+
+                    if ( currentProductions.size() == 1 && !cacheCost )
+                    {
+                        //  Only one production, just return its cost.
+                        genReturnValue(output, productionCost);
+                    }
+                    else if ( i == 0 )
+                    {
+                        //  Emit an assignment with no if guards
+                        //  if this is the first (or only) assignment.
+                        genAssignment(output, bestCostVar, productionCost);
+                        output.println();
+                    }
+                    else
+                    {
+                        //  If the cost uses a computation, put it in a temp.
+                        if ( !production.computesConstantCost(productions) )
+                        {
+                            if ( ! currentCostDeclared )
+                            {
+                                genLocalVar(output, "int", "currentCost", productionCost);
+                                currentCostDeclared = true;
+                            }
+                            else
+                            {
+                                genAssignment(output, "currentCost", productionCost);
+                            }
+                            
+                            productionCost = "currentCost";
+                        }
+
+                        genIf(output, codeEmitter.genCmpLess(bestCostVar, productionCost));
+                        indentNextLine();
+                        genAssignment(output, bestCostVar, productionCost);
+                    }
+                }
+
+                if ( cacheCost )
+                    //  End the if statement.
+                    genEndBlock(output);
+
+                if ( cacheCost || hasMultipleProductions )
+                    genReturnValue(output, bestCostVar);
+                // else the cost has already been returned.
+            }
+
+            genEndBlock(output); // end case without unreachable break
+        }
+        genEndSwitch(output);
+        genReturnValue(output, codeEmitter.genMaxIntValue());
+        genEndBlock(output); // getCost
+
+        /*
+         *  ** Emit getRule()  **
+         */
+        genDeclareMethod(output, Modifier.PUBLIC, "int", "getRule", "int", "goalState" );
+        genBeginBlock(output);
+
+        genSwitch(output, "goalState");
+
+        for ( Map.Entry<String, ArrayList<JBurgProduction>> productionsByNonterminal: productions.entrySet() )
+        {
+            genCase(output, getNonterminal(productionsByNonterminal.getKey()));
+
+            ArrayList<JBurgProduction> currentProductions = productionsByNonterminal.getValue();
+
+            //  Try to resolve the optimal production at compiler-compile time.
+            JBurgProduction optimalProduction = findOptimalProduction(currentProductions, productions);
+
+            if ( optimalProduction != null )
+            {
+                genReturnValue(output, Integer.toString(optimalProduction.getReduceAction().getIndex()));
+            }
+            else
+            {
+                // Emit the analogous compile-time computation.
+                genLocalVar(output, "int", "rule", NO_FEASIBLE_RULE);
+                genLocalVar(output, "int", "bestCost", codeEmitter.genMaxIntValue());
+
+                //  Emit this declaration at its first use.
+                boolean currentCostDeclared = false;
+
+                for ( int i = 0; i < currentProductions.size(); i++ )
+                {
+                    boolean costIsConstant = false;
+                    String currentProductionCost;
+
+                    //  Extract required information from the production:
+                    //  what is its cost, and is it constant?
+                    JBurgProduction production = currentProductions.get(i);
+
+                    if ( production.computesConstantCost(productions) )
+                    {
+                        int constantCost = production.getConstantCost(productions);
+                        costIsConstant = constantCost < Integer.MAX_VALUE;
+                        currentProductionCost = Integer.toString(constantCost);
+                    }
+                    else
+                    {
+                        currentProductionCost = getCostForProduction(production, productions);
+                    }
+
+                    //  Generate the necessary tests and assignments.
+
+                    //  If the first production's cost is constant
+                    //  (and feasible, which has been checked and
+                    //  incorporated into costIsConstant), then 
+                    //  testing it against bestCost is a tautology.
+                    boolean needComparison = (!costIsConstant) || i > 0;
+
+                    if ( needComparison )
+                    {
+                        //  If the cost uses a computation, put it in a temp.
+                        if ( ! costIsConstant )
+                        {
+                            if ( ! currentCostDeclared )
+                            {
+                                genLocalVar(output, "int", "currentCost", currentProductionCost);
+                                currentCostDeclared = true;
+                            }
+                            else
+                            {
+                                genAssignment(output, "currentCost", currentProductionCost);
+                            }
+                            currentProductionCost = "currentCost";
+                        }
+
+                        genIf(output, codeEmitter.genCmpLess("bestCost", currentProductionCost));
+                        genBeginBlock(output);
+                    }
+
+                    //  Track the new best cost if there's another choice to be evaluated.
+                    if ( i + 1 < currentProductions.size() )
+                        genAssignment(output, "bestCost", currentProductionCost);
+
+                    genAssignment(output, "rule", Integer.toString(production.getReduceAction().getIndex()));
+
+                    if ( needComparison )
+                        genEndBlock(output);
+                }
+
+                genReturnValue(output,"rule");
+            }
+
+            genEndBlock(output);  // endCase() without unreachable break statement
+        }
+
+        genEndSwitch(output);
+        genReturnValue(output, NO_FEASIBLE_RULE);
+        genEndBlock(output); // getRule
+
+        /*
+         *  ** Emit getArity()  **
+         */
+        genDeclareMethod(output, Modifier.PUBLIC, "int", "getArity");
+        genBeginBlock(output);
+
+        if ( fixedArity )
+        {
+            genReturnValue(output, Integer.toString(nominalArity));
+        }
+        else if ( nominalArity != 0 )
+        {
+            //  TODO: Need an emitter method to get the correct size() call
+            genReturnValue(output, String.format("%d + %s", nominalArity, "narySubtrees.size()" ));
+        }
+        else
+        {
+            genReturnValue(output, "narySubtrees.size()" );
+        }
+
+        genEndBlock(output); // getArity
+
+        /*
+         *  **  Emit overrides for getNthChild() and addChild() if necessary  **
+         */
+        if ( nominalArity > 0 || ! fixedArity )
+        {
+            //  getNthChild
+            genDeclareMethod( output, Modifier.PUBLIC, "JBurgAnnotation", "getNthChild", "int", "index");
+
+            genBeginBlock(output); // getNthChild
+            genSwitch(output, "index");
+
+            for ( int i = 0; i < nominalArity; i++ )
+            {
+                genLine(output, String.format("case %d:", i));
+                genSingleLineBlock(output, String.format("return subtree%d;", i));
+            }
+
+            genDefaultCase(output);
+            if ( ! fixedArity )
+            {
+                if ( nominalArity == 0 )
+                    genLine(output, "return narySubtrees.get(index);");
+                else
+                    genLine(output, String.format("return narySubtrees.get(index - %d);", nominalArity));
+            }
+            else
+            {
+                genThrow(output, "\"Invalid index \" + index");
+            }
+            genEndBlock(output);  //  genEndCase() without unreachable break
+
+            genEndBlock(output); // switch
+            genEndBlock(output); // getNthChild
+
+            //  addChild
+            genDeclareMethod(output, Modifier.PUBLIC, "void", "addChild", "JBurgAnnotation", "child");
+
+            genBeginBlock(output); // addChild
+
+            for ( int i = 0; i < nominalArity; i++ )
+            {
+                if ( i == 0 )
+                    genLine(output, String.format("if ( subtree%d == null )", i));
+                else
+                    genLine(output, String.format("else if ( subtree%d == null )", i));
+                genSingleLineBlock(output, String.format("subtree%d = child;", i));
+            }
+
+            if ( nominalArity > 0 )
+                genLine(output, String.format("else"));
+
+            if ( ! fixedArity )
+                genSingleLineBlock(output, "narySubtrees.add(child);");
+            else
+                genSingleLineBlock(output, "throw new IllegalStateException(\"too many children\");");
+
+            genEndBlock(output); // addChild
+        }
+
+        //  Emit caches for any costs that require a function call;
+        //  the BURM's contract says these functions are only called once.
+        Set<String> emittedCosts = new HashSet<String>();
+
+        for ( ArrayList<ClosureRecord> closures: closureCosts.values() )
+            for ( ClosureRecord closure: closures )
+                if ( closure.hasCostFunction() && emittedCosts.add(closure.getCachedCost()) )
+                    emitCachedCost(output, closure.getCachedCost(), closure.getCost("m_node")); 
+
+        for ( JBurgRule rule: currentRules )
+        {
+            if ( rule.needsCostFunction() )
+                emitGetCostForRule(output, rule, factored_variables);
+
+            if ( rule.hasCostFunction() && emittedCosts.add(rule.getCachedCost()) )
+                emitCachedCost(output, rule.getCachedCost(), rule.getCost("m_node")); 
+        }
+
+        //  Finish the compressed annotation's class declaration.
+        genEndBlock(output);
+    }
+
+    /**
+     *  @param productions - a list of productions.
+     *  @return true if the list has one member and that member has a constant cost.
+     */
+    boolean hasConstantCost(ArrayList<JBurgProduction> productions)
+    {
+        return productions != null &&
+            productions.size() == 1 && 
+            productions.get(0) instanceof JBurgRule &&
+            ((JBurgRule)productions.get(0)).hasConstantCost();
+    }
+
+    /**
+     *  @return the expression to use for a production's cost;
+     *    this may be an arithmetic expression or a call
+     *    to an implementation method, depending on
+     *    the production's complexity.
+     */
+    String getCostForProduction(JBurgProduction production, Multimap<String,JBurgProduction> productions)
+    {
+        if ( production instanceof JBurgRule )
+        {
+            JBurgRule rule = (JBurgRule) production;
+            if ( rule.needsCostFunction() )
+                return genCallMethod(null, getCostingFunctionForRule(rule), "goalState");
+            else
+                return getCompositeCostOfRule(rule);
+        }
+        else
+        {
+            return ((ClosureRecord)production).getCostComputation(productions);
+        }
+    }
+
+    /**
+     *  Do compiler-compile time dynamic programming to choose
+     *  the best alternative from a list of possibilities.
+     *  @param currentProductions - the list of productions to choose from.
+     *  @param allProductions - the entire set of productions active at the site.
+     */
+    JBurgProduction findOptimalProduction(List<JBurgProduction> currentProductions, Multimap<String, JBurgProduction> allProductions)
+    {
+        int bestCost = Integer.MAX_VALUE;
+        JBurgProduction result = null;
+
+        for ( JBurgProduction production: currentProductions )
+        {
+            if ( production.computesConstantCost(allProductions) )
+            {
+                int cost = production.getConstantCost(allProductions);
+                if ( cost < bestCost )
+                {
+                    result = production;
+                    bestCost = cost;
+                }
+            }
+            else
+            {
+                //  Can't be determined at compiler-compile time.
+                result = null;
+                break;
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     *  Emit a rule's cost function.
+     *  @param output - the current output stream.
+     *  @param rule - the rule to emit.
+     *  @param factored_variables - the list of pattern matchers it's worth factoring.
+     */
+    void emitGetCostForRule(PrintStream output, JBurgRule rule, Map<JBurgPatternMatcher,String> factored_variables )
+    {
+        assert(rule.needsCostFunction());
+
+        genDeclareMethod(output, Modifier.PRIVATE, "int", getCostingFunctionForRule(rule), "int", "goalState");
+        genBeginBlock(output);
+        {
+            for ( String var_decl: factored_variables.values() )
+                if ( rule.patternMatcher.usesFactoredVariable(var_decl) )
+                genLine(output, var_decl);
+
+            output.println();
+
+            String patternMatch = rule.patternMatcher.generatePatternRecognizer(
+                    codeEmitter,
+                    "this",
+                    JBurgGenerator.this.adapter2
+                );
+
+            // The pattern match may be null if it's trival.
+            if ( patternMatch != null )
+            {
+                genIf(output, patternMatch);
+                indentNextLine();
+            }
+
+            genReturnValue(output, getCompositeCostOfRule(rule));
+
+            if ( patternMatch != null )
+            {
+                genLine(output, codeEmitter.genElse());
+                indentNextLine();
+                genReturnValue(output, codeEmitter.genMaxIntValue());
+            }
+
+        }
+        genEndBlock(output);
+    }
+
+    /**
+     *  @return a unique identifier for the method that computes
+     *    a rule's cost (note: this is not the rule's cost function).
+     */
+    String getCostingFunctionForRule(JBurgRule rule)
+    {
+        if ( ! ruleNumber.containsKey(rule) )
+            ruleNumber.put(rule, String.format("getCostForRule%x", ruleNumber.size()));
+        return ruleNumber.get(rule);
+    }
+
+    private Map<JBurgRule,String> ruleNumber = new HashMap<JBurgRule, String>();
+    
+    /**
+     *  Emit the cache field and accessor function for a cached 
+     *    result of a cost function call.
+     */
+    void emitCachedCost(PrintStream output, String functionName, String payload)
+    {
+        //  Strip () characters.
+        functionName = functionName.substring(0, functionName.length() -2);
+
+        String varName = String.format("cachedCostFunctionResult_%h", functionName);
+
+        genInstanceField( output, Modifier.PRIVATE, "int", varName, UNINITIALIZED);
+
+        genDeclareMethod( output, Modifier.PRIVATE, "int", functionName );
+
+        genBeginBlock(output);
+        {
+            genIf ( output, codeEmitter.genCmpEquality(varName, UNINITIALIZED, true) );
+            indentNextLine();
+            genAssignment(output, varName, payload);
+            genReturnValue(output, varName);
+        }
+        genEndBlock(output);
+    }
+
+    /**
+     *  Add up all of a rule's cost factors.
+     *  @param rule - the rule of interest.
+     *  @return an overflow-safe addition of the
+     *    rule's cost and the costs of its subtrees.
+     */
+    String getCompositeCostOfRule(JBurgRule rule)
+    {
+        String subtreeCost = null;
+
+        for ( JBurgPatternMatcher subgoal: rule.patternMatcher.getParameterizedSubtrees() )
+        {
+            String subgoalCost = subgoal.generateCost(codeEmitter, "this");
+
+            if ( subgoalCost != null )
+                subtreeCost = codeEmitter.genAddition(subtreeCost, codeEmitter.genCast("long", subgoalCost));
+        }
+
+        if ( subtreeCost != null )
+            return codeEmitter.genOverflowSafeAdd(rule.getCachedCost(), subtreeCost);
+        else
+            return rule.getCachedCost();
+    }
+
+    /**
+     *  Emit the factored path variables into a map,
+     *  and mutate the affected pattern matchers
+     *  to refer to the factored variable.
+     *  @param commonSubtrees - the map of common subtrees to their pattern matchers.
+     */
+    Map<JBurgPatternMatcher,String> emitFactoredPathVariables(Multimap<JBurgPatternMatcher, JBurgPatternMatcher> commonSubtrees)
+    {
+        Map<JBurgPatternMatcher,String> result = new TreeMap<JBurgPatternMatcher, String>();
+
+        int varNum = 0;
+        for ( Map.Entry<JBurgPatternMatcher, ArrayList<JBurgPatternMatcher>> factored: commonSubtrees.entrySet() )
+        {
+            String varName = String.format("factoredPath_%d", varNum++);
+
+            result.put(factored.getKey(), codeEmitter.genLocalVar("JBurgAnnotation", varName, factored.getKey().generateFactoredReference(codeEmitter)));
+
+            for ( JBurgPatternMatcher matcher: factored.getValue() )
+                matcher.factoredPath = varName;
+        }
+    
+        return result;
+    }
+
+    /**
+     *  ClosuresByNonterminal is a convenience class that holds
+     *  closure sets grouped by nonterminal; the NT may
+     *  be the production or the antecedent, depending on usage.
+     */
+    class ClosuresByNonterminal extends Multimap<String, ClosureRecord>
+    {
+        /**
+         *  Add a closure record.
+         *  @param nt - the nonterminal that indexes this closure.
+         *    May be the production or the antecedent.
+         */
+        public void addClosure(String nt, ClosureRecord closure)
+        {
+            if ( ! this.getSet(nt).contains(closure) )
+                this.getSet(nt).add(closure);
+        }
+    }
+
+    /**
+     *  A ClosureGraph holds the graph of closures that
+     *  can be reached from a starting nonterminal.
+     */
+    class ClosureGraph extends ClosuresByNonterminal
+    {
+        /**
+         *  Sweep the set of nonterminal-to-nonterminal rules and
+         *  add any that can be produced by the most recently
+         *  added nonterminal.
+         *  @param currentNT - the most recently added nonterminal.
+         */
+        void addClosures(String currentNT)
+        {
+            addClosures(currentNT, currentNT);
+        }
+
+        /**
+         *  Sweep the set of nonterminal-to-nonterminal rules and
+         *  add any that can be produced by the most recently
+         *  added nonterminal.
+         *  @param currentNT - the most recently added nonterminal.
+         *  @param patternNT - the nonterminal produced by the pattern match.
+         */
+        void addClosures(String currentNT, String patternNT)
+        {
+            if ( JBurgGenerator.this.closureSets.containsKey(currentNT) )
+            {
+                for ( ClosureRecord closure: JBurgGenerator.this.closureSets.get(currentNT) )
+                {
+                    String newNT = closure.getGoalState();
+
+                    //  Can't replace the pattern with a closure.
+                    if ( !newNT.equals(patternNT) )
+                    {
+                        if ( ! this.containsKey ( newNT ) )
+                        {
+                            super.addClosure(newNT, closure);
+                            addClosures(newNT);
+                        }
+                        else
+                        {
+                            //  Add this closure, but its consequent
+                            //  closures are already in the set so
+                            //  it's not necessary to add them.
+                            super.addClosure(newNT, closure);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     *  @return the current Logger implementation;
+     *    constructs a Logger that emits messages
+     *    to stdout/stderr.
+     */
+    Logger getLogger()
+    {
+        if ( null == this.logger )
+            this.logger = new Logger(true, true, true);
+        return this.logger;
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genAssignment and prints the result.
+     */
+	void genAssignment(PrintStream output, String lvalue, String rvalue)
+	{
+		genLine(output, codeEmitter.genAssignment( lvalue, rvalue ) );
+	}
+
+    /**
+     *  Convenience method wraps codeEmitter.genComment and prints the result.
+     */
+    void genComment(PrintStream output, String comment)
+    {
+        genLine(output, codeEmitter.genComment(comment) );
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genLine and prints the result.
+     *  @param output - the current output stream
+     *  @param contents - the contents to write.  Contents will be trimmed
+     *    of whitespace before output.
+     */
+    void genLine(PrintStream output, String contents)
+    {
+        String formattedContents = contents.trim();
+
+        if ( doIndentNextLine )
+            formattedContents = "\t" + formattedContents;
+
+        doIndentNextLine = false;
+        output.print(codeEmitter.genLine(formattedContents) );
+    }
+
+    /**
+     *  When set, indent the next line of output to note that
+     *  the statement on that line is an if/then branch.
+     *  @see {@link #indentNextLine()}, which sets this field.
+     *  @see {@link #genLine(PrintStream,String)}, which consumes this field and resets it.
+     *
+     */
+    boolean doIndentNextLine = false;
+
+    /**
+     *  Signal that the next line should be indented.
+     *  @see {@link #doIndentNextLine}, which this method sets.
+     */
+    void indentNextLine()
+    {
+        doIndentNextLine = true;
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genLine and prints the result,
+     *  with an extra level of nesting added to improve readability.
+     */
+    void genSingleLineBlock (PrintStream output, String contents)
+    {
+        indentNextLine();
+        genLine(output, contents);
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genBeginBlock and prints the result.
+     */
+    void genBeginBlock(PrintStream output)
+    {
+        output.print(codeEmitter.genBeginBlock());
+    }
+    
+    /**
+     *  Convenience method wraps codeEmitter.genEndBlock and prints the result.
+     */
+    void genEndBlock(PrintStream output)
+    {
+        output.print(codeEmitter.genEndBlock());
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genSwitch and prints the result.
+     */
+    void genSwitch(PrintStream output, String expression)
+    {
+        genLine(output, codeEmitter.genSwitch(expression) );
+        genBeginBlock(output);
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genEndSwitch and prints the result.
+     */
+    void genEndSwitch(PrintStream output)
+    {
+        genLine(output, codeEmitter.genEndSwitch() );
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genCase and prints the result.
+     */
+    void genCase(PrintStream output, String selector )
+    {
+        output.print(codeEmitter.genCase(selector));
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genEndCase and prints the result.
+     */
+    void genEndCase(PrintStream output)
+    {
+        output.print(codeEmitter.genEndCase());
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genDefaultCase and prints the result.
+     */
+    void genDefaultCase(PrintStream output)
+    {
+        genLine(output, codeEmitter.genDefaultCase());
+        genBeginBlock(output);
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genIf and prints the result.
+     */
+    void genIf(PrintStream output, String condition )
+    {
+        genLine(output, codeEmitter.genIf(condition));
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genReturnValue and prints the result.
+     */
+    void genReturnValue(PrintStream output, String value )
+    {
+        genLine(output, codeEmitter.genReturnValue(value) + codeEmitter.genEndStmt());
+    }
+
+    /**
+     *  Convenience method prints an expression as a statement.
+     */
+    void genExpressionStmt(PrintStream output, String expr)
+    {
+        genLine(output, expr + codeEmitter.genEndStmt());
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genDeclareMethod and prints the result.
+     */
+    void genDeclareMethod(PrintStream output, int modifiers, String returnClass, String name, String[][] plist, Class<?>[] exceptions )
+    {
+        output.print(codeEmitter.declareMethod(modifiers, returnClass, name, plist, exceptions));
+    }
+
+    /**
+     *  Convenience method declares BURM methods that don't throw.
+     */
+    void genDeclareMethod(PrintStream output, int modifiers, String returnClass, String name, Object ... plist)
+    {
+        genDeclareMethod(output, modifiers, returnClass, name, genFormals(plist), throwsNothing);
+    }
+
+    /**
+     *  Convenience method declares BURM methods that don't throw or have parameters.
+     */
+    void genDeclareMethod(PrintStream output, int modifiers, String returnClass, String name)
+    {
+        genDeclareMethod(output, modifiers, returnClass, name, noFormalParameters, throwsNothing);
+    }
+
+    /**
+     *  Generate formal parameters from a list of type, name pairs.
+     *  @param raw_formals - a variadic list of type, name pairs.
+     *  @return the raw formals marshalled into a 2-dimensional array.
+     */
+    String[][] genFormals(Object ... raw_formals)
+    {
+        assert(raw_formals.length % 2 == 0): "n-ary formal parameters must be in (type, name) pairs";
+
+        String[][] plist = new String[raw_formals.length/2][2];
+        for ( int i = 0; i < raw_formals.length - 1; i += 2  )
+        {
+            plist[i/2][0] = raw_formals[i].toString();
+            plist[i/2][1] = raw_formals[i+1].toString();
+        }
+
+        return plist;
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genLocalVar and prints the result.
+     */
+    void genLocalVar(PrintStream output, String varType, String varName, String initializer)
+    {
+        genLine(output, codeEmitter.genLocalVar(varType, varName, initializer));
+        output.println();
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genLocalVar and prints the result.
+     */
+    void genLocalVar(PrintStream output, String varType, String varName)
+    {
+        genLocalVar(output, varType, varName, null);
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genThrow and prints the result.
+     */
+    void genThrow( PrintStream output, String diagnostic )
+    {
+        genLine(output, codeEmitter.genThrow(diagnostic) + codeEmitter.genEndStmt() );
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genInstanceField and prints the result.
+     */
+    void genInstanceField(PrintStream output, int modifiers, String type, String name, String initializer)
+    { 
+        genLine(output, codeEmitter.genInstanceField(modifiers, type, name, initializer));
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genGetGoalState.
+     */
+    String getNonterminal(String raw_nt)
+    {
+        return codeEmitter.genGetGoalState(raw_nt);
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genCallMethod for methods with no parameters.
+     */
+    String genCallMethod(String stem, String methodName)
+    {
+        return codeEmitter.genCallMethod(stem, methodName, noActualParameters );
+    }
+    
+    /**
+     *  Convenience method wraps codeEmitter.genCallMethod for methods with one parameter.
+     */
+    String genCallMethod(String stem, String methodName, Object param)
+    {
+        return codeEmitter.genCallMethod(stem, methodName, new String[] { param.toString() } );
+    }
+
+    /**
+     *  Convenience method wraps codeEmitter.genCallMethod for methods with two parameters.
+     */
+    String genCallMethod(String stem, String methodName, Object param1, Object param2)
+    {
+        return codeEmitter.genCallMethod(stem, methodName, new String[] { param1.toString(), param2.toString() } );
+    }
+
+
+    /**
+     *  @return the input string with its outer
+     *    layer of {} brackets stripped off.
+     */
+    public static String stripBrackets(String src)
+    {
+        int startchar = src.indexOf('{') + 1;
+        int lentoend = src.lastIndexOf('}');
+        return src.substring( startchar, lentoend-startchar );
+    
+    }
+
+    /**
+     *  Generate the correct calling sequence to get the nth child
+     *  of an input i-node.
+     *  @param indexTerm - the n in nth child.
+     */
+    String genGetNthChild(String indexTerm)
+    {
+		return this.adapter2 != null ?
+		    genCallMethod("this", "getNthChild", JBurgGenerator.initalParamName, indexTerm):
+	        this.iNodeAdapter.genGetNthChild( JBurgGenerator.initalParamName, indexTerm, codeEmitter );
+    }
+		
+    /**
+     *  Generate the calling sequence for the label() method.
+     */
+    String genCallLabel(String indexTerm)
+    {
+        return genCallMethod(
+            "this",
+            "label",
+            codeEmitter.genCast( 
+                iNodeClass, 
+                genGetNthChild(indexTerm)
+            )
+        );
+    }
+
+    /**
+     *  @return true if any rules in the list have n-ary operands.
+     */
+    private boolean hasNaryness(Collection<JBurgRule> rules)
+    {
+        boolean result = false;
+
+        for ( JBurgRule rule: rules )
+            result |= rule.patternMatcher.hasNaryness();
+
+        return result;
+    }
+
+    /**
+     *  @return the minumum arity of a list of rules.
+     */
+    private int getMinumumArity(Collection<JBurgRule> rules)
+    {
+        int result = Integer.MAX_VALUE;
+
+        for ( JBurgRule rule: rules )
+            result = Math.min(result, rule.patternMatcher.getNominalArity());
+
+        return result;
+    }
+
+    /**
+     *  @return the name of a JBurgAnnotation specialized subclass.
+     */
+    String getSpecializedClassName(ArrayList<JBurgRule> rules )
+    {
+        if ( hasNaryness(rules) )
+            return String.format("JBurgAnnotation_%s_%d_n", rules.get(0).getOperator(), getMinumumArity(rules));
+        else
+            return String.format("JBurgAnnotation_%s_%d", rules.get(0).getOperator(), getMinumumArity(rules));
+    }
+
+    /**
+     *  RulesByOperatorAndArity is a multidimensional associative store that
+     *  sorts JBurgRules into equivalence classes, where the equivalaence
+     *  relation is "these rules can share an annotation object."
+     */
+    class RulesByOperatorAndArity
+    {
+        /**
+         *  Unsorted rules.
+         */
+        Multimap<String, JBurgRule> unsortedRules = new Multimap<String, JBurgRule>();
+
+        Map<String, Iterable<ArrayList<JBurgRule>>> sortedRules = null;
+
+        public void addAll(List<JBurgRule> rules)
+        {
+            assert sortedRules == null;
+
+            String operator = rules.get(0).getOperator();
+            this.unsortedRules.addAllToSet(operator, rules);
+        }
+
+        public void addRule(JBurgRule rule)
+        {
+            assert sortedRules == null;
+            this.unsortedRules.addToSet(rule.getOperator(), rule);
+        }
+
+        public Set<String> getOperators()
+        {
+            return unsortedRules.keySet();
+        }
+
+        public Iterable<ArrayList<JBurgRule>> getRulesFor(String operator)
+        {
+            if ( this.sortedRules == null )
+            {
+                this.sortedRules = new TreeMap<String, Iterable<ArrayList<JBurgRule>>>();
+
+                for ( String op: getOperators() )
+                    this.sortedRules.put(op, sortRules(this.unsortedRules.get(op)));
+            }
+
+            return this.sortedRules.get(operator);
+        }
+
+        private Iterable<ArrayList<JBurgRule>> sortRules( ArrayList<JBurgRule> unsorted_rules)
+        {
+            //  Find the minumum arity of all n-ary patterns;
+            //  any rule with arity >= this limit gets sorted
+            //  into the "variable-arity" bucket.
+            int arity_requires_variable = Integer.MAX_VALUE;
+
+            for ( JBurgRule rule: unsorted_rules )
+                if ( rule.patternMatcher.hasNaryness() )
+                    arity_requires_variable = Math.min(arity_requires_variable, rule.patternMatcher.getNominalArity());
+
+            Multimap<Integer, JBurgRule> rules = new Multimap<Integer, JBurgRule>(); 
+
+            for ( JBurgRule rule: unsorted_rules )
+            {
+                //  All n-ary patterns and any fixed-arity patterns that
+                //  overlap with n-ary patterns go into a common annotation;
+                //  fixed-arity patterns of arity less than the smallest
+                //  n-ary arity can't be confused with an n-ary pattern
+                //  and can go in their own annotation.
+                Integer key = 
+                    rule.patternMatcher.getNominalArity() < arity_requires_variable?
+                    rule.patternMatcher.getNominalArity():
+                    arity_requires_variable;
+
+                rules.addToSet(key,rule);
+            }
+
+            return rules.values();
+        }
+
+    }
+}
diff --git a/compiler-jx/.classpath b/compiler-jx/.classpath
index 31d0100..36d2686 100644
--- a/compiler-jx/.classpath
+++ b/compiler-jx/.classpath
@@ -17,5 +17,6 @@
 	<classpathentry combineaccessrules="false" kind="src" path="/compiler-common"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/compiler-externc"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/compiler-test-utils"/>
+	<classpathentry kind="lib" path="/compiler-externc/target/test-classes"/>
 	<classpathentry kind="output" path="target/classes"/>
 </classpath>
diff --git a/compiler-jx/pom.xml b/compiler-jx/pom.xml
index 628aedc..4608343 100644
--- a/compiler-jx/pom.xml
+++ b/compiler-jx/pom.xml
@@ -1,137 +1,237 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.apache.royale.compiler</groupId>
-    <artifactId>royale-compiler-parent</artifactId>
-    <version>0.9.4</version>
-  </parent>
-
-  <artifactId>compiler-jx</artifactId>
-  <version>0.9.4</version>
-
-  <name>Apache Royale: Compiler: Compiler-JX</name>
-
-  <build>
-    <plugins>
-      <!-- Make the surefire execute all unit-tests -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <version>2.19</version>
-        <configuration>
-          <includes>
-            <include>org/**/Test*.java</include>
-          </includes>
-          <excludes>
-            <exclude>**/TestRoyaleFile.java</exclude>
-            <exclude>**/TestRoyaleMXML*.java</exclude>
-            <exclude>**/TestSourceMap*.java</exclude>
-            <exclude>**/TestMXML*.java</exclude>
-            <exclude>**/TestRoyaleClass.java</exclude>
-            <exclude>**/TestTypedefsCompile.java</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-failsafe-plugin</artifactId>
-        <version>2.18.1</version>
-        <configuration>
-          <includes>
-            <include>**/TestMXML*.java</include>
-          </includes>
-          <excludes>
-            <exclude>**/TestTypedefsCompile.java</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>compiler-common</artifactId>
-      <version>0.9.4</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>compiler-externc</artifactId>
-      <version>0.9.4</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>compiler</artifactId>
-      <version>0.9.4</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-compress</artifactId>
-      <version>1.11</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-lang</groupId>
-      <artifactId>commons-lang</artifactId>
-      <version>2.6</version>
-    </dependency>
-
-    <dependency>
-      <groupId>args4j</groupId>
-      <artifactId>args4j</artifactId>
-      <version>2.33</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.javascript</groupId>
-      <artifactId>closure-compiler</artifactId>
-      <version>v20170626</version>
-    </dependency>
-    <dependency>
-      <groupId>org.clojure</groupId>
-      <artifactId>google-closure-library</artifactId>
-      <version>0.0-20170809-b9c14c6b</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>compiler-test-utils</artifactId>
-      <version>0.9.4</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>4.10</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>compiler-externc</artifactId>
-      <version>0.9.4</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    
-  </dependencies>
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+

+  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.

+

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+  <modelVersion>4.0.0</modelVersion>

+

+  <parent>

+    <groupId>org.apache.royale.compiler</groupId>

+    <artifactId>royale-compiler-parent</artifactId>

+    <version>0.9.6</version>

+  </parent>

+

+  <artifactId>compiler-jx</artifactId>

+  <version>0.9.6</version>

+

+  <name>Apache Royale: Compiler: Compiler-JX</name>

+

+  <build>

+    <plugins>

+      <plugin>

+        <groupId>io.github.zlika</groupId>

+        <artifactId>reproducible-build-maven-plugin</artifactId>

+        <version>0.9</version>

+      </plugin>

+      <plugin>

+        <artifactId>maven-resources-plugin</artifactId>

+        <version>3.1.0</version>

+        <executions>

+          <execution>

+            <id>copy-externc-resources</id>

+            <phase>process-test-resources</phase>

+            <goals>

+              <goal>copy-resources</goal>

+            </goals>

+          <configuration>

+          <outputDirectory>${basedir}/../compiler-externc/target</outputDirectory>

+            <resources>

+              <resource>

+                <directory>${basedir}/../compiler-externc/src/test/config</directory>

+              </resource>

+            </resources>

+          </configuration>

+        </execution>

+        <execution>

+          <id>copy-custom-resources</id>

+          <phase>process-test-resources</phase>

+          <goals>

+            <goal>copy-resources</goal>

+          </goals>

+          <configuration>

+            <outputDirectory>${basedir}/target</outputDirectory>

+            <resources>

+              <resource>

+                <directory>${basedir}/src/test/config</directory>

+              </resource>

+            </resources>

+          </configuration>

+        </execution>

+      </executions>

+    </plugin>

+      <!-- Make the surefire execute all unit-tests -->

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-surefire-plugin</artifactId>

+        <version>2.19</version>

+        <configuration>

+          <includes>

+            <include>org/**/Test*.java</include>

+          </includes>

+          <excludes>

+            <exclude>**/TestRoyaleFile.java</exclude>

+            <exclude>**/TestRoyaleMXML*.java</exclude>

+            <exclude>**/TestSourceMap*.java</exclude>

+            <exclude>**/TestMXML*.java</exclude>

+            <exclude>**/TestRoyaleClass.java</exclude>

+            <exclude>**/TestTypedefsCompile.java</exclude>

+          </excludes>

+        </configuration>

+      </plugin>

+

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-failsafe-plugin</artifactId>

+        <version>2.18.1</version>

+        <configuration>

+          <includes>

+            <include>**/TestMXML*.java</include>

+          </includes>

+          <excludes>

+            <exclude>**/TestTypedefsCompile.java</exclude>

+          </excludes>

+        </configuration>

+      </plugin>

+    

+      <plugin>

+        <groupId>org.codehaus.mojo</groupId>

+        <artifactId>exec-maven-plugin</artifactId>

+        <version>1.5.0</version>

+        <executions>

+          <execution>

+              <id>generate-test-js-typedefs</id>

+              <phase>test-compile</phase>

+              <goals>

+                  <goal>exec</goal>

+              </goals>

+              <configuration>

+                  <executable>java</executable>

+                  <arguments>

+                      <argument>-classpath</argument>

+                      <classpath />

+                      <arguments>org.apache.royale.compiler.clients.EXTERNC</arguments>

+                      <argument>-load-config+=../compiler-externc/src/test/config/externc-config.xml</argument>

+                  </arguments>

+              </configuration>

+          </execution>

+          <execution>

+              <id>generate-test-js-swc</id>

+              <phase>test-compile</phase>

+              <goals>

+                  <goal>exec</goal>

+              </goals>

+              <configuration>

+                  <executable>java</executable>

+                  <arguments>

+                      <argument>-classpath</argument>

+                      <classpath />

+                      <arguments>org.apache.royale.compiler.clients.COMPJSC</arguments>

+                      <argument>-targets=SWF</argument>

+                      <argument>-load-config+=../compiler-externc/target/compile-as-config.xml</argument>

+                      <argument>-output=../compiler-externc/target/js.swc</argument>

+                  </arguments>

+              </configuration>

+          </execution>

+          <execution>

+              <id>generate-test-custom-swc</id>

+              <phase>test-compile</phase>

+              <goals>

+                  <goal>exec</goal>

+              </goals>

+              <configuration>

+                  <executable>java</executable>

+                  <arguments>

+                      <argument>-classpath</argument>

+                      <classpath />

+                      <arguments>org.apache.royale.compiler.clients.COMPJSC</arguments>

+                      <argument>-load-config+=target/compile-js-config.xml</argument>

+                      <argument>-output=target/custom.swc</argument>

+                  </arguments>

+              </configuration>

+          </execution>

+        </executions>

+      </plugin>

+    </plugins>

+  </build>

+

+  <dependencies>

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>compiler-common</artifactId>

+      <version>0.9.6</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>compiler-externc</artifactId>

+      <version>0.9.6</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>compiler</artifactId>

+      <version>0.9.6</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.commons</groupId>

+      <artifactId>commons-compress</artifactId>

+      <version>1.11</version>

+    </dependency>

+    <dependency>

+      <groupId>commons-lang</groupId>

+      <artifactId>commons-lang</artifactId>

+      <version>2.6</version>

+    </dependency>

+

+    <dependency>

+      <groupId>args4j</groupId>

+      <artifactId>args4j</artifactId>

+      <version>2.33</version>

+    </dependency>

+    <dependency>

+      <groupId>com.google.javascript</groupId>

+      <artifactId>closure-compiler</artifactId>

+      <version>v20181210</version>

+    </dependency>

+    <dependency>

+      <groupId>org.clojure</groupId>

+      <artifactId>google-closure-library</artifactId>

+      <version>0.0-20170809-b9c14c6b</version>

+    </dependency>

+

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>compiler-test-utils</artifactId>

+      <version>0.9.6</version>

+      <scope>test</scope>

+    </dependency>

+    <dependency>

+      <groupId>junit</groupId>

+      <artifactId>junit</artifactId>

+      <version>4.10</version>

+      <scope>test</scope>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>compiler-externc</artifactId>

+      <version>0.9.6</version>

+      <type>test-jar</type>

+      <scope>test</scope>

+    </dependency>

+    

+  </dependencies>

+

+</project>

diff --git a/compiler-jx/src/main/java/com/google/javascript/jscomp/CollapsePropertiesWithModuleSupport.java b/compiler-jx/src/main/java/com/google/javascript/jscomp/CollapsePropertiesWithModuleSupport.java
new file mode 100644
index 0000000..2593e82
--- /dev/null
+++ b/compiler-jx/src/main/java/com/google/javascript/jscomp/CollapsePropertiesWithModuleSupport.java
@@ -0,0 +1,1035 @@
+/*
+ * Copyright 2006 The Closure Compiler Authors.
+ *
+ * Licensed 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 com.google.javascript.jscomp;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
+import com.google.common.io.Files;
+import com.google.javascript.jscomp.CompilerOptions.PropertyCollapseLevel;
+import com.google.javascript.jscomp.GlobalNamespace.Name;
+import com.google.javascript.jscomp.GlobalNamespace.Ref;
+import com.google.javascript.jscomp.Normalize.PropagateConstantAnnotationsOverVars;
+import com.google.javascript.rhino.IR;
+import com.google.javascript.rhino.InputId;
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.Node;
+import com.google.javascript.rhino.Token;
+import com.google.javascript.rhino.TokenStream;
+import com.google.javascript.rhino.jstype.JSType;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Apache Royale copied CollapseProperties and modified it to handle
+ * Royale modules.
+ * 
+ * Flattens global objects/namespaces by replacing each '.' with '$' in
+ * their names. This reduces the number of property lookups the browser has
+ * to do and allows the {@link RenameVars} pass to shorten namespaced names.
+ * For example, goog.events.handleEvent() -> goog$events$handleEvent() -> Za().
+ *
+ * <p>If a global object's name is assigned to more than once, or if a property
+ * is added to the global object in a complex expression, then none of its
+ * properties will be collapsed (for safety/correctness).
+ *
+ * <p>If, after a global object is declared, it is never referenced except when
+ * its properties are read or set, then the object will be removed after its
+ * properties have been collapsed.
+ *
+ * <p>Uninitialized variable stubs are created at a global object's declaration
+ * site for any of its properties that are added late in a local scope.
+ *
+ * <p> Static properties of constructors are always collapsed, unsafely!
+ * For other objects: if, after an object is declared, it is referenced directly
+ * in a way that might create an alias for it, then none of its properties will
+ * be collapsed.
+ * This behavior is a safeguard to prevent the values associated with the
+ * flattened names from getting out of sync with the object's actual property
+ * values. For example, in the following case, an alias a$b, if created, could
+ * easily keep the value 0 even after a.b became 5:
+ * <code> a = {b: 0}; c = a; c.b = 5; </code>.
+ *
+ * <p>This pass doesn't flatten property accesses of the form: a[b].
+ *
+ * <p>For lots of examples, see the unit test.
+ *
+ */
+class CollapsePropertiesWithModuleSupport implements CompilerPass {
+  // Warnings
+  static final DiagnosticType UNSAFE_NAMESPACE_WARNING =
+      DiagnosticType.warning(
+          "JSC_UNSAFE_NAMESPACE",
+          "incomplete alias created for namespace {0}");
+
+  static final DiagnosticType NAMESPACE_REDEFINED_WARNING =
+      DiagnosticType.warning(
+          "JSC_NAMESPACE_REDEFINED",
+          "namespace {0} should not be redefined");
+
+  static final DiagnosticType UNSAFE_THIS = DiagnosticType.warning(
+      "JSC_UNSAFE_THIS",
+      "dangerous use of ''this'' in static method {0}");
+
+  private final AbstractCompiler compiler;
+  private final PropertyCollapseLevel propertyCollapseLevel;
+
+  /** Global namespace tree */
+  private List<Name> globalNames;
+
+  /** Maps names (e.g. "a.b.c") to nodes in the global namespace tree */
+  private Map<String, Name> nameMap;
+  
+  /** name of a source file we can use to inject other code */
+  private String sourceFileName;
+
+  /** name of the file of renamed variables */
+  private File varRenameMapFile;
+  
+  /** list of renamed variables */
+  private ArrayList<String> renamedVars = null;
+  
+  /** list of aliases that are also in externs */
+  private List<String> externAliases;
+
+  /** list of aliases that came from goog.provides */
+  private List<String> providedAliases = new ArrayList<String>();
+  
+  /** list of namespaces that came from goog.provides */
+  private List<String> providedNamespaces = new ArrayList<String>();
+  
+  CollapsePropertiesWithModuleSupport(AbstractCompiler compiler, PropertyCollapseLevel propertyCollapseLevel, String sourceFileName, File varRenameMapFile) {
+    this.compiler = compiler;
+    this.propertyCollapseLevel = propertyCollapseLevel;
+    this.varRenameMapFile = varRenameMapFile;
+    this.sourceFileName = sourceFileName;
+  }
+
+  @Override
+  public void process(Node externs, Node root) {
+	// ProcessClosurePrimitives runs first and builds up an initial list of
+	// namespaces from goog.provides that were also in externs.
+	externAliases = ProcessClosurePrimitivesWithModuleSupport.externedAliases.get(externs);
+	int n = externAliases.size();
+	for (int i = 0; i < n; i++)
+	{
+		String s = externAliases.get(i);
+		String t = s.replace(".", "$");
+		externAliases.set(i, t);
+	}
+	// ProcessClosurePrimitives runs first and builds up an initial list of
+	// namespaces from goog.provides.
+	providedAliases = ProcessClosurePrimitivesWithModuleSupport.providedsMap.get(externs);
+	providedNamespaces.addAll(providedAliases);
+	n = providedAliases.size();
+	for (int i = 0; i < n; i++)
+	{
+		String s = providedAliases.get(i);
+		String t = s.replace(".", "$");
+		providedAliases.set(i, t);
+	}	
+	/*
+	 * The goal is to use knowledge of the aliases and which are externed
+	 * to eliminate warnings and allow aliases in more places than
+	 * closure compiler would normally.  Closure compiler doesn't want to
+	 * collapse things found in externs, but we want to collapse
+	 * them to save size and need to collapse them when there are
+	 * overrides in the module of a collapsed property in code
+	 * in the main app.  Or when the code in the main app is calling
+	 * via an interface and code in the module implements that
+	 * interface.
+	 */
+	
+    GlobalNamespace namespace = new GlobalNamespace(compiler, externs, root);
+    nameMap = namespace.getNameIndex();
+    globalNames = namespace.getNameForest();
+    checkNamespaces();
+
+    for (Name name : globalNames) {
+      flattenReferencesToCollapsibleDescendantNames(name, name.getBaseName());
+    }
+
+    // We collapse property definitions after collapsing property references
+    // because this step can alter the parse tree above property references,
+    // invalidating the node ancestry stored with each reference.
+    for (Name name : globalNames) {
+      collapseDeclarationOfNameAndDescendants(name, name.getBaseName());
+    }
+
+    // This shouldn't be necessary, this pass should already be setting new constants as constant.
+    // TODO(b/64256754): Investigate.
+    (new PropagateConstantAnnotationsOverVars(compiler, false)).process(externs, root);
+  }
+
+  
+  private boolean canCollapse(Name name) {
+    if (!name.canCollapse()) {
+      return false;
+    }
+
+    if (propertyCollapseLevel == PropertyCollapseLevel.MODULE_EXPORT && !name.isModuleExport()) {
+      return false;
+    }
+
+    return true;
+  }
+
+  private boolean canEliminate(Name name) {
+    if (!name.canEliminate()) {
+      return false;
+    }
+
+    if (name.props == null
+        || name.props.isEmpty()
+        || propertyCollapseLevel != PropertyCollapseLevel.MODULE_EXPORT) {
+      return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Runs through all namespaces (prefixes of classes and enums), and checks if any of them have
+   * been used in an unsafe way.
+   */
+  private void checkNamespaces() {
+    for (Name name : nameMap.values()) {
+      if (name.isNamespaceObjectLit()
+          && (name.getAliasingGets() > 0
+              || name.getLocalSets() + name.getGlobalSets() > 1
+              || name.getDeleteProps() > 0)) {
+        boolean initialized = name.getDeclaration() != null;
+        for (Ref ref : name.getRefs()) {
+          if (ref == name.getDeclaration()) {
+            continue;
+          }
+
+          if (ref.type == Ref.Type.DELETE_PROP) {
+            if (initialized) {
+              warnAboutNamespaceRedefinition(name, ref);
+            }
+          } else if (
+              ref.type == Ref.Type.SET_FROM_GLOBAL
+              || ref.type == Ref.Type.SET_FROM_LOCAL) {
+            if (initialized && !isSafeNamespaceReinit(ref) && 
+            		!providedNamespaces.contains(name.getFullName())) {
+              warnAboutNamespaceRedefinition(name, ref);
+            }
+
+            initialized = true;
+          } else if (ref.type == Ref.Type.ALIASING_GET) {
+        	  if (!providedNamespaces.contains(name.getFullName()) &&
+        			  !ref.name.inExterns())
+        		  warnAboutNamespaceAliasing(name, ref);
+          }
+        }
+      }
+    }
+  }
+
+  static boolean isSafeNamespaceReinit(Ref ref) {
+    // allow "a = a || {}" or "var a = a || {}" or "var a;"
+    Node valParent = getValueParent(ref);
+    Node val = valParent.getLastChild();
+    if (val != null && val.isOr()) {
+      Node maybeName = val.getFirstChild();
+      if (ref.node.matchesQualifiedName(maybeName)) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Gets the parent node of the value for any assignment to a Name.
+   * For example, in the assignment
+   * {@code var x = 3;}
+   * the parent would be the NAME node.
+   */
+  private static Node getValueParent(Ref ref) {
+    // there are four types of declarations: VARs, LETs, CONSTs, and ASSIGNs
+    Node n = ref.node.getParent();
+    return (n != null && NodeUtil.isNameDeclaration(n)) ? ref.node : ref.node.getParent();
+  }
+
+  /**
+   * Reports a warning because a namespace was aliased.
+   *
+   * @param nameObj A namespace that is being aliased
+   * @param ref The reference that forced the alias
+   */
+  private void warnAboutNamespaceAliasing(Name nameObj, Ref ref) {
+    compiler.report(
+        JSError.make(ref.node,
+                     UNSAFE_NAMESPACE_WARNING, nameObj.getFullName()));
+  }
+
+  /**
+   * Reports a warning because a namespace was redefined.
+   *
+   * @param nameObj A namespace that is being redefined
+   * @param ref The reference that set the namespace
+   */
+  private void warnAboutNamespaceRedefinition(Name nameObj, Ref ref) {
+    compiler.report(
+        JSError.make(ref.node,
+                     NAMESPACE_REDEFINED_WARNING, nameObj.getFullName()));
+  }
+
+  /**
+   * Flattens all references to collapsible properties of a global name except
+   * their initial definitions. Recurs on subnames.
+   *
+   * @param n An object representing a global name
+   * @param alias The flattened name for {@code n}
+   */
+  private void flattenReferencesToCollapsibleDescendantNames(
+      Name n, String alias) {
+    if (n.props == null || n.isCollapsingExplicitlyDenied()) {
+      return;
+    }
+
+    for (Name p : n.props) {
+      String propAlias = appendPropForAlias(alias, p.getBaseName());
+
+      boolean isAllowedToCollapse =
+          propertyCollapseLevel != PropertyCollapseLevel.MODULE_EXPORT || p.isModuleExport();
+
+      if (isAllowedToCollapse && (p.canCollapse() || wasCollapsed(propAlias) || shouldCollapse(propAlias))) {
+        flattenReferencesTo(p, propAlias);
+      } else if (isAllowedToCollapse
+          && p.isSimpleStubDeclaration()
+          && !p.isCollapsingExplicitlyDenied()) {
+        flattenSimpleStubDeclaration(p, propAlias);
+      }
+
+      flattenReferencesToCollapsibleDescendantNames(p, propAlias);
+    }
+  }
+  
+  /**
+   * we should collapse aliases in the module no matter what.
+   * 
+   * @param propAlias The alias being considered.
+   * @return true If alias is for a namespace provided in the module.
+   */
+  private boolean shouldCollapse(String propAlias) {
+	if (providedAliases.contains(propAlias))
+	{
+        InputId inputId = new InputId(
+              sourceFileName);
+        CompilerInput compilerInput = compiler.getInput(inputId);
+        Node nameNode = IR.name(propAlias);
+        Node child = IR.var(nameNode);
+        compilerInput.getAstRoot(compiler).addChildToBack(child);
+        compiler.reportChangeToEnclosingScope(child);
+        if (!externAliases.contains(propAlias))
+          externAliases.add(propAlias);
+		return true;
+	}
+	return false;
+}
+
+  /**
+   * See if this property was collapse by the loading app.
+   * @param propAlias The alias that might have been collapsed.
+   * @return true If the alias was collapsed in the loading app.
+   */
+  private boolean wasCollapsed(String propAlias) {
+    if (varRenameMapFile == null)
+      return false;
+
+    if (renamedVars == null)
+    {
+      List<String> fileLines;
+
+      renamedVars = new ArrayList<String>();
+      try {
+        fileLines = Files.readLines(varRenameMapFile, Charset.defaultCharset());
+        for (String line : fileLines)
+        {
+          int c = line.indexOf(":");
+          if (c > 0)
+          {
+            renamedVars.add(line.substring(0, c));
+          }
+        }
+      } catch (IOException e) {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+      }
+    }
+    if (renamedVars.contains(propAlias) || externAliases.contains(propAlias)) {
+      // if it was collapsed, add a var for it in our source for now.
+      // RemoveUnusedNames will move the var before it gets code-genned.
+      InputId inputId = new InputId(
+          sourceFileName);
+      CompilerInput compilerInput = compiler.getInput(inputId);
+      Node nameNode = IR.name(propAlias);
+      Node child = IR.var(nameNode);
+      compilerInput.getAstRoot(compiler).addChildToBack(child);
+      compiler.reportChangeToEnclosingScope(child);
+      // add it to the list of aliases from the externs so
+      // rename vars can know what variables we created here.
+      if (!externAliases.contains(propAlias))
+        externAliases.add(propAlias);
+      return true;
+    }
+    return false;
+  }
+
+
+  /**
+   * Flattens a stub declaration.
+   * This is mostly a hack to support legacy users.
+   */
+  private void flattenSimpleStubDeclaration(Name name, String alias) {
+    Ref ref = Iterables.getOnlyElement(name.getRefs());
+    Node nameNode = NodeUtil.newName(
+        compiler, alias, ref.node,
+        name.getFullName());
+    Node varNode = IR.var(nameNode).useSourceInfoIfMissingFrom(nameNode);
+
+    checkState(ref.node.getParent().isExprResult());
+    Node parent = ref.node.getParent();
+    Node grandparent = parent.getParent();
+    grandparent.replaceChild(parent, varNode);
+    compiler.reportChangeToEnclosingScope(varNode);
+  }
+
+  /**
+   * Flattens all references to a collapsible property of a global name except
+   * its initial definition.
+   *
+   * @param n A global property name (e.g. "a.b" or "a.b.c.d")
+   * @param alias The flattened name (e.g. "a$b" or "a$b$c$d")
+   */
+  private void flattenReferencesTo(Name n, String alias) {
+    String originalName = n.getFullName();
+    for (Ref r : n.getRefs()) {
+      if (r == n.getDeclaration()) {
+        // Declarations are handled separately.
+        continue;
+      }
+      Node rParent = r.node.getParent();
+      // There are two cases when we shouldn't flatten a reference:
+      // 1) Object literal keys, because duplicate keys show up as refs.
+      // 2) References inside a complex assign. (a = x.y = 0). These are
+      //    called TWIN references, because they show up twice in the
+      //    reference list. Only collapse the set, not the alias.
+      if (!r.node.isFromExterns() && !NodeUtil.isObjectLitKey(r.node) && (r.getTwin() == null || r.isSet())) {
+        flattenNameRef(alias, r.node, rParent, originalName);
+      }
+    }
+
+    // Flatten all occurrences of a name as a prefix of its subnames. For
+    // example, if {@code n} corresponds to the name "a.b", then "a.b" will be
+    // replaced with "a$b" in all occurrences of "a.b.c", "a.b.c.d", etc.
+    if (n.props != null) {
+      for (Name p : n.props) {
+        flattenPrefixes(alias, p, 1);
+      }
+    }
+  }
+
+  /**
+   * Flattens all occurrences of a name as a prefix of subnames beginning
+   * with a particular subname.
+   *
+   * @param n A global property name (e.g. "a.b.c.d")
+   * @param alias A flattened prefix name (e.g. "a$b")
+   * @param depth The difference in depth between the property name and
+   *    the prefix name (e.g. 2)
+   */
+  private void flattenPrefixes(String alias, Name n, int depth) {
+    // Only flatten the prefix of a name declaration if the name being
+    // initialized is fully qualified (i.e. not an object literal key).
+    String originalName = n.getFullName();
+    Ref decl = n.getDeclaration();
+    if (decl != null && decl.node != null && !decl.node.isFromExterns() && decl.node.isGetProp()) {
+      flattenNameRefAtDepth(alias, decl.node, depth, originalName);
+    }
+
+    for (Ref r : n.getRefs()) {
+      if (r == decl) {
+        // Declarations are handled separately.
+        continue;
+      }
+
+      // References inside a complex assign (a = x.y = 0)
+      // have twins. We should only flatten one of the twins.
+      if (r.getTwin() == null || r.isSet()) {
+    	if (r.node != null && !r.node.isFromExterns())
+    	  flattenNameRefAtDepth(alias, r.node, depth, originalName);
+      }
+    }
+
+    if (n.props != null) {
+      for (Name p : n.props) {
+        flattenPrefixes(alias, p, depth + 1);
+      }
+    }
+  }
+
+  /**
+   * Flattens a particular prefix of a single name reference.
+   *
+   * @param alias A flattened prefix name (e.g. "a$b")
+   * @param n The node corresponding to a subproperty name (e.g. "a.b.c.d")
+   * @param depth The difference in depth between the property name and
+   *    the prefix name (e.g. 2)
+   * @param originalName String version of the property name.
+   */
+  private void flattenNameRefAtDepth(String alias, Node n, int depth,
+      String originalName) {
+    // This method has to work for both GETPROP chains and, in rare cases,
+    // OBJLIT keys, possibly nested. That's why we check for children before
+    // proceeding. In the OBJLIT case, we don't need to do anything.
+    Token nType = n.getToken();
+    boolean isQName = nType == Token.NAME || nType == Token.GETPROP;
+    boolean isObjKey = NodeUtil.isObjectLitKey(n);
+    checkState(isObjKey || isQName);
+    if (isQName) {
+      for (int i = 1; i < depth && n.hasChildren(); i++) {
+        n = n.getFirstChild();
+      }
+      if (n.isGetProp() && n.getFirstChild().isGetProp()) {
+        flattenNameRef(alias, n.getFirstChild(), n, originalName);
+      }
+    }
+  }
+
+  /**
+   * Replaces a GETPROP a.b.c with a NAME a$b$c.
+   *
+   * @param alias A flattened prefix name (e.g. "a$b")
+   * @param n The GETPROP node corresponding to the original name (e.g. "a.b")
+   * @param parent {@code n}'s parent
+   * @param originalName String version of the property name.
+   */
+  private void flattenNameRef(String alias, Node n, Node parent,
+      String originalName) {
+    Preconditions.checkArgument(
+        n.isGetProp(), "Expected GETPROP, found %s. Node: %s", n.getToken(), n);
+
+    // BEFORE:
+    //   getprop
+    //     getprop
+    //       name a
+    //       string b
+    //     string c
+    // AFTER:
+    //   name a$b$c
+    Node ref = NodeUtil.newName(compiler, alias, n, originalName);
+    NodeUtil.copyNameAnnotations(n.getLastChild(), ref);
+    if (parent != null && parent.isCall() && n == parent.getFirstChild()) {
+      // The node was a call target, we are deliberately flatten these as
+      // we node the "this" isn't provided by the namespace. Mark it as such:
+      parent.putBooleanProp(Node.FREE_CALL, true);
+    }
+
+    JSType type = n.getJSType();
+    if (type != null) {
+      ref.setJSType(type);
+    }
+
+    if (parent == null)
+    {
+      // in some cases parent is null (not sure why)
+      // but ref is a StringNode and a child of n
+      // is a StringNode so replace that StringNode
+      parent = n;
+      n = n.getFirstChild();
+	  parent.replaceChild(n, ref);
+    }
+    else
+    {
+	  parent.replaceChild(n, ref);
+	  Node enclosingScopeNode = NodeUtil.getEnclosingChangeScopeRoot(n.getParent());
+	  if (enclosingScopeNode != null)
+	    compiler.reportChangeToEnclosingScope(ref);
+    }
+  }
+
+  /**
+   * Collapses definitions of the collapsible properties of a global name.
+   * Recurs on subnames that also represent JavaScript objects with
+   * collapsible properties.
+   *
+   * @param n A node representing a global name
+   * @param alias The flattened name for {@code n}
+   */
+  private void collapseDeclarationOfNameAndDescendants(Name n, String alias) {
+    boolean canCollapseChildNames = n.canCollapseUnannotatedChildNames();
+
+    // Handle this name first so that nested object literals get unrolled.
+    if (canCollapse(n)/* && !externStrings.contains(n.getName())*/) {
+      updateGlobalNameDeclaration(n, alias, canCollapseChildNames);
+    }
+
+    if (n.props == null) {
+      return;
+    }
+    for (Name p : n.props) {
+      collapseDeclarationOfNameAndDescendants(p, appendPropForAlias(alias, p.getBaseName()));
+    }
+  }
+
+  /**
+   * Updates the initial assignment to a collapsible property at global scope
+   * by adding a VAR stub and collapsing the property. e.g. c = a.b = 1; => var a$b; c = a$b = 1;
+   * This specifically handles "twinned" assignments, which are those where the assignment is also
+   * used as a reference and which need special handling.
+   *
+   * @param alias The flattened property name (e.g. "a$b")
+   * @param refName The name for the reference being updated.
+   * @param ref An object containing information about the assignment getting updated
+   */
+  private void updateTwinnedDeclaration(String alias, Name refName, Ref ref) {
+    checkNotNull(ref.getTwin());
+    // Don't handle declarations of an already flat name, just qualified names.
+    if (!ref.node.isGetProp()) {
+      return;
+    }
+    Node rvalue = ref.node.getNext();
+    Node parent = ref.node.getParent();
+    Node grandparent = parent.getParent();
+
+    if (rvalue != null && rvalue.isFunction()) {
+      checkForHosedThisReferences(rvalue, refName.docInfo, refName);
+    }
+
+    // Create the new alias node.
+    Node nameNode =
+        NodeUtil.newName(compiler, alias, grandparent.getFirstChild(), refName.getFullName());
+    NodeUtil.copyNameAnnotations(ref.node.getLastChild(), nameNode);
+
+    // BEFORE:
+    // ... (x.y = 3);
+    //
+    // AFTER:
+    // var x$y;
+    // ... (x$y = 3);
+
+    Node current = grandparent;
+    Node currentParent = grandparent.getParent();
+    for (;
+        !currentParent.isScript() && !currentParent.isBlock();
+        current = currentParent, currentParent = currentParent.getParent()) {}
+
+    // Create a stub variable declaration right
+    // before the current statement.
+    Node stubVar = IR.var(nameNode.cloneTree()).useSourceInfoIfMissingFrom(nameNode);
+    currentParent.addChildBefore(stubVar, current);
+
+    parent.replaceChild(ref.node, nameNode);
+    compiler.reportChangeToEnclosingScope(nameNode);
+  }
+
+  /**
+   * Updates the first initialization (a.k.a "declaration") of a global name.
+   * This involves flattening the global name (if it's not just a global
+   * variable name already), collapsing object literal keys into global
+   * variables, declaring stub global variables for properties added later
+   * in a local scope.
+   *
+   * It may seem odd that this function also takes care of declaring stubs
+   * for direct children. The ultimate goal of this function is to eliminate
+   * the global name entirely (when possible), so that "middlemen" namespaces
+   * disappear, and to do that we need to make sure that all the direct children
+   * will be collapsed as well.
+   *
+   * @param n An object representing a global name (e.g. "a", "a.b.c")
+   * @param alias The flattened name for {@code n} (e.g. "a", "a$b$c")
+   * @param canCollapseChildNames Whether it's possible to collapse children of
+   *     this name. (This is mostly passed for convenience; it's equivalent to
+   *     n.canCollapseChildNames()).
+   */
+  private void updateGlobalNameDeclaration(
+      Name n, String alias, boolean canCollapseChildNames) {
+    Ref decl = n.getDeclaration();
+    if (decl == null) {
+      // Some names do not have declarations, because they
+      // are only defined in local scopes.
+      return;
+    }
+
+    if (decl.node == null)
+    	return; // package stubs (org.apache.royale)
+    
+    switch (decl.node.getParent().getToken()) {
+      case ASSIGN:
+        updateGlobalNameDeclarationAtAssignNode(
+            n, alias, canCollapseChildNames);
+        break;
+      case VAR:
+      case LET:
+      case CONST:
+        updateGlobalNameDeclarationAtVariableNode(n, canCollapseChildNames);
+        break;
+      case FUNCTION:
+        updateGlobalNameDeclarationAtFunctionNode(n, canCollapseChildNames);
+        break;
+      case CLASS:
+        updateGlobalNameDeclarationAtClassNode(n, canCollapseChildNames);
+        break;
+      default:
+        break;
+    }
+  }
+
+  /**
+   * Updates the first initialization (a.k.a "declaration") of a global name
+   * that occurs at an ASSIGN node. See comment for
+   * {@link #updateGlobalNameDeclaration}.
+   *
+   * @param n An object representing a global name (e.g. "a", "a.b.c")
+   * @param alias The flattened name for {@code n} (e.g. "a", "a$b$c")
+   */
+  private void updateGlobalNameDeclarationAtAssignNode(
+      Name n, String alias, boolean canCollapseChildNames) {
+    // NOTE: It's important that we don't add additional nodes
+    // (e.g. a var node before the exprstmt) because the exprstmt might be
+    // the child of an if statement that's not inside a block).
+
+    // All qualified names - even for variables that are initially declared as LETS and CONSTS -
+    // are being declared as VAR statements, but this is not incorrect because
+    // we are only collapsing for global names.
+    Ref ref = n.getDeclaration();
+    Node rvalue = ref.node.getNext();
+    if (ref.getTwin() != null) {
+      updateTwinnedDeclaration(alias, ref.name, ref);
+      return;
+    }
+    Node varNode = new Node(Token.VAR);
+    Node varParent = ref.node.getAncestor(3);
+    Node grandparent = ref.node.getAncestor(2);
+    boolean isObjLit = rvalue.isObjectLit();
+    boolean insertedVarNode = false;
+
+    if (isObjLit && canEliminate(n)) {
+      // Eliminate the object literal altogether.
+      varParent.replaceChild(grandparent, varNode);
+      ref.node = null;
+      insertedVarNode = true;
+      compiler.reportChangeToEnclosingScope(varNode);
+    } else if (!n.isSimpleName()) {
+      // Create a VAR node to declare the name.
+      if (rvalue.isFunction()) {
+        checkForHosedThisReferences(rvalue, n.docInfo, n);
+      }
+
+      compiler.reportChangeToEnclosingScope(rvalue);
+      ref.node.getParent().removeChild(rvalue);
+
+      Node nameNode = NodeUtil.newName(compiler,
+          alias, ref.node.getAncestor(2), n.getFullName());
+
+      JSDocInfo info = NodeUtil.getBestJSDocInfo(ref.node.getParent());
+      if (ref.node.getLastChild().getBooleanProp(Node.IS_CONSTANT_NAME)
+          || (info != null && info.isConstant())) {
+        nameNode.putBooleanProp(Node.IS_CONSTANT_NAME, true);
+      }
+
+      if (info != null) {
+        varNode.setJSDocInfo(info);
+      }
+      varNode.addChildToBack(nameNode);
+      nameNode.addChildToFront(rvalue);
+      varParent.replaceChild(grandparent, varNode);
+
+      // Update the node ancestry stored in the reference.
+      ref.node = nameNode;
+      insertedVarNode = true;
+      compiler.reportChangeToEnclosingScope(varNode);
+    }
+
+    if (canCollapseChildNames) {
+      if (isObjLit) {
+        declareVariablesForObjLitValues(
+            n, alias, rvalue, varNode, varNode.getPrevious(), varParent);
+      }
+
+      addStubsForUndeclaredProperties(n, alias, varParent, varNode);
+    }
+
+    if (insertedVarNode) {
+      if (!varNode.hasChildren()) {
+        varParent.removeChild(varNode);
+      }
+    }
+  }
+
+  /**
+   * Warns about any references to "this" in the given FUNCTION. The function
+   * is getting collapsed, so the references will change.
+   */
+  private void checkForHosedThisReferences(Node function, JSDocInfo docInfo,
+      final Name name) {
+    // A function is getting collapsed. Make sure that if it refers to "this",
+    // it must be a constructor, interface, record, arrow function, or documented with @this.
+    boolean isAllowedToReferenceThis =
+        (docInfo != null && (docInfo.isConstructorOrInterface() || docInfo.hasThisType()))
+        || function.isArrowFunction();
+    if (!isAllowedToReferenceThis) {
+      NodeTraversal.traverse(compiler, function.getLastChild(),
+          new NodeTraversal.AbstractShallowCallback() {
+            @Override
+            public void visit(NodeTraversal t, Node n, Node parent) {
+              if (n.isThis()) {
+                compiler.report(
+                    JSError.make(n, UNSAFE_THIS, name.getFullName()));
+              }
+            }
+          });
+    }
+  }
+
+  /**
+   * Updates the first initialization (a.k.a "declaration") of a global name that occurs at a VAR
+   * node. See comment for {@link #updateGlobalNameDeclaration}.
+   *
+   * @param n An object representing a global name (e.g. "a")
+   */
+  private void updateGlobalNameDeclarationAtVariableNode(
+      Name n, boolean canCollapseChildNames) {
+    if (!canCollapseChildNames) {
+      return;
+    }
+
+    Ref ref = n.getDeclaration();
+    String name = ref.node.getString();
+    Node rvalue = ref.node.getFirstChild();
+    Node variableNode = ref.node.getParent();
+    Node grandparent = variableNode.getParent();
+
+    boolean isObjLit = rvalue.isObjectLit();
+
+    if (isObjLit) {
+      declareVariablesForObjLitValues(
+          n, name, rvalue, variableNode, variableNode.getPrevious(), grandparent);
+    }
+
+    addStubsForUndeclaredProperties(n, name, grandparent, variableNode);
+
+    if (isObjLit && canEliminate(n)) {
+      variableNode.removeChild(ref.node);
+      compiler.reportChangeToEnclosingScope(variableNode);
+      if (!variableNode.hasChildren()) {
+        grandparent.removeChild(variableNode);
+      }
+
+      // Clear out the object reference, since we've eliminated it from the
+      // parse tree.
+      ref.node = null;
+    }
+  }
+
+  /**
+   * Updates the first initialization (a.k.a "declaration") of a global name
+   * that occurs at a FUNCTION node. See comment for
+   * {@link #updateGlobalNameDeclaration}.
+   *
+   * @param n An object representing a global name (e.g. "a")
+   */
+  private void updateGlobalNameDeclarationAtFunctionNode(
+      Name n, boolean canCollapseChildNames) {
+    if (!canCollapseChildNames || !canCollapse(n)) {
+      return;
+    }
+
+    Ref ref = n.getDeclaration();
+    String fnName = ref.node.getString();
+    addStubsForUndeclaredProperties(n, fnName, ref.node.getAncestor(2), ref.node.getParent());
+  }
+
+  /**
+   * Updates the first initialization (a.k.a "declaration") of a global name that occurs at a CLASS
+   * node. See comment for {@link #updateGlobalNameDeclaration}.
+   *
+   * @param n An object representing a global name (e.g. "a")
+   */
+  private void updateGlobalNameDeclarationAtClassNode(Name n, boolean canCollapseChildNames) {
+    if (!canCollapseChildNames || !canCollapse(n)) {
+      return;
+    }
+
+    Ref ref = n.getDeclaration();
+    String className = ref.node.getString();
+    addStubsForUndeclaredProperties(
+        n, className, ref.node.getAncestor(2), ref.node.getParent());
+  }
+
+  /**
+   * Declares global variables to serve as aliases for the values in an object literal, optionally
+   * removing all of the object literal's keys and values.
+   *
+   * @param alias The object literal's flattened name (e.g. "a$b$c")
+   * @param objlit The OBJLIT node
+   * @param varNode The VAR node to which new global variables should be added as children
+   * @param nameToAddAfter The child of {@code varNode} after which new variables should be added
+   *     (may be null)
+   * @param varParent {@code varNode}'s parent
+   */
+  private void declareVariablesForObjLitValues(
+      Name objlitName,
+      String alias,
+      Node objlit,
+      Node varNode,
+      Node nameToAddAfter,
+      Node varParent) {
+    int arbitraryNameCounter = 0;
+    boolean discardKeys = !objlitName.shouldKeepKeys();
+
+    for (Node key = objlit.getFirstChild(), nextKey; key != null;
+         key = nextKey) {
+      Node value = key.getFirstChild();
+      nextKey = key.getNext();
+
+      // A computed property, or a get or a set can not be rewritten as a VAR.
+      if (key.isGetterDef() || key.isSetterDef() || key.isComputedProp()) {
+        continue;
+      }
+
+      // We generate arbitrary names for keys that aren't valid JavaScript
+      // identifiers, since those keys are never referenced. (If they were,
+      // this object literal's child names wouldn't be collapsible.) The only
+      // reason that we don't eliminate them entirely is the off chance that
+      // their values are expressions that have side effects.
+      boolean isJsIdentifier = !key.isNumber() && TokenStream.isJSIdentifier(key.getString());
+      String propName = isJsIdentifier ? key.getString() : String.valueOf(++arbitraryNameCounter);
+
+      // If the name cannot be collapsed, skip it.
+      String qName = objlitName.getFullName() + '.' + propName;
+      Name p = nameMap.get(qName);
+      if (p != null && !canCollapse(p)) {
+        continue;
+      }
+
+      String propAlias = appendPropForAlias(alias, propName);
+      Node refNode = null;
+      if (discardKeys) {
+        objlit.removeChild(key);
+        value.detach();
+        // Don't report a change here because the objlit has already been removed from the tree.
+      } else {
+        // Substitute a reference for the value.
+        refNode = IR.name(propAlias);
+        if (key.getBooleanProp(Node.IS_CONSTANT_NAME)) {
+          refNode.putBooleanProp(Node.IS_CONSTANT_NAME, true);
+        }
+
+        key.replaceChild(value, refNode);
+        compiler.reportChangeToEnclosingScope(refNode);
+      }
+
+      // Declare the collapsed name as a variable with the original value.
+      Node nameNode = IR.name(propAlias);
+      nameNode.addChildToFront(value);
+      if (key.getBooleanProp(Node.IS_CONSTANT_NAME)) {
+        nameNode.putBooleanProp(Node.IS_CONSTANT_NAME, true);
+      }
+      Node newVar = IR.var(nameNode).useSourceInfoIfMissingFromForTree(key);
+      if (nameToAddAfter != null) {
+        varParent.addChildAfter(newVar, nameToAddAfter);
+      } else {
+        varParent.addChildBefore(newVar, varNode);
+      }
+      compiler.reportChangeToEnclosingScope(newVar);
+      nameToAddAfter = newVar;
+
+      // Update the global name's node ancestry if it hasn't already been
+      // done. (Duplicate keys in an object literal can bring us here twice
+      // for the same global name.)
+      if (isJsIdentifier && p != null) {
+        if (!discardKeys) {
+          Ref newAlias =
+              p.getDeclaration().cloneAndReclassify(Ref.Type.ALIASING_GET);
+          newAlias.node = refNode;
+          p.addRef(newAlias);
+        }
+
+        p.getDeclaration().node = nameNode;
+
+        if (value.isFunction()) {
+          checkForHosedThisReferences(value, key.getJSDocInfo(), p);
+        }
+      }
+    }
+  }
+
+  /**
+   * Adds global variable "stubs" for any properties of a global name that are only set in a local
+   * scope or read but never set.
+   *
+   * @param n An object representing a global name (e.g. "a", "a.b.c")
+   * @param alias The flattened name of the object whose properties we are adding stubs for (e.g.
+   *     "a$b$c")
+   * @param parent The node to which new global variables should be added as children
+   * @param addAfter The child of after which new variables should be added
+   */
+  private void addStubsForUndeclaredProperties(Name n, String alias, Node parent, Node addAfter) {
+    checkState(n.canCollapseUnannotatedChildNames(), n);
+    checkArgument(NodeUtil.isStatementBlock(parent), parent);
+    checkNotNull(addAfter);
+    if (n.props == null) {
+      return;
+    }
+    for (Name p : n.props) {
+      if (p.needsToBeStubbed()) {
+        String propAlias = appendPropForAlias(alias, p.getBaseName());
+        Node nameNode = IR.name(propAlias);
+        Node newVar = IR.var(nameNode).useSourceInfoIfMissingFromForTree(addAfter);
+        parent.addChildAfter(newVar, addAfter);
+        addAfter = newVar;
+        compiler.reportChangeToEnclosingScope(newVar);
+        // Determine if this is a constant var by checking the first
+        // reference to it. Don't check the declaration, as it might be null.
+        if (p.getRefs().get(0).node.getLastChild().getBooleanProp(
+            Node.IS_CONSTANT_NAME)) {
+          nameNode.putBooleanProp(Node.IS_CONSTANT_NAME, true);
+          compiler.reportChangeToEnclosingScope(nameNode);
+        }
+      }
+    }
+  }
+
+  private String appendPropForAlias(String root, String prop) {
+    if (prop.indexOf('$') != -1) {
+      // Encode '$' in a property as '$0'. Because '0' cannot be the
+      // start of an identifier, this will never conflict with our
+      // encoding from '.' -> '$'.
+      prop = prop.replace("$", "$0");
+    }
+    String result = root + '$' + prop;
+    int id = 1;
+    while (nameMap.containsKey(result)) {
+      result = root + '$' + prop + '$' + id;
+      id++;
+    }
+    return result;
+  }
+}
diff --git a/compiler-jx/src/main/java/com/google/javascript/jscomp/CompilerMapFetcher.java b/compiler-jx/src/main/java/com/google/javascript/jscomp/CompilerMapFetcher.java
index 5fbb7ae..a9c818b 100644
--- a/compiler-jx/src/main/java/com/google/javascript/jscomp/CompilerMapFetcher.java
+++ b/compiler-jx/src/main/java/com/google/javascript/jscomp/CompilerMapFetcher.java
@@ -22,7 +22,7 @@
 public class CompilerMapFetcher
 {
 
-    private static final long serialVersionUID = 2021530437904249081L;
+    //private static final long serialVersionUID = 2021530437904249081L;
 
     public CompilerMapFetcher()
     {
diff --git a/compiler-jx/src/main/java/com/google/javascript/jscomp/ProcessClosurePrimitivesWithModuleSupport.java b/compiler-jx/src/main/java/com/google/javascript/jscomp/ProcessClosurePrimitivesWithModuleSupport.java
new file mode 100644
index 0000000..68ee660
--- /dev/null
+++ b/compiler-jx/src/main/java/com/google/javascript/jscomp/ProcessClosurePrimitivesWithModuleSupport.java
@@ -0,0 +1,1811 @@
+/*
+ * Copyright 2006 The Closure Compiler Authors.
+ *
+ * Licensed 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 com.google.javascript.jscomp;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.javascript.jscomp.ClosurePrimitiveErrors.INVALID_CLOSURE_CALL_SCOPE_ERROR;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.javascript.jscomp.GlobalNamespace.Name;
+import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback;
+import com.google.javascript.jscomp.parsing.JsDocInfoParser;
+import com.google.javascript.rhino.IR;
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.JSDocInfoBuilder;
+import com.google.javascript.rhino.JSTypeExpression;
+import com.google.javascript.rhino.Node;
+import com.google.javascript.rhino.Token;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import javax.annotation.Nullable;
+
+/**
+ * Apache Royale copied ProcessClosurePrimitives and modified it to handle
+ * Royale modules.
+ * 
+ * Replaces goog.provide calls, removes goog.{require,requireType} calls, verifies that each
+ * goog.{require,requireType} has a corresponding goog.provide, and performs some Closure-pecific
+ * simplifications.
+ *
+ * @author chrisn@google.com (Chris Nokleberg)
+ */
+class ProcessClosurePrimitivesWithModuleSupport extends AbstractPostOrderCallback implements HotSwapCompilerPass {
+
+  static final DiagnosticType NULL_ARGUMENT_ERROR = DiagnosticType.error(
+      "JSC_NULL_ARGUMENT_ERROR",
+      "method \"{0}\" called without an argument");
+
+  static final DiagnosticType EXPECTED_OBJECTLIT_ERROR = DiagnosticType.error(
+      "JSC_EXPECTED_OBJECTLIT_ERROR",
+      "method \"{0}\" expected an object literal argument");
+
+  static final DiagnosticType EXPECTED_STRING_ERROR =
+      DiagnosticType.error(
+          "JSC_EXPECTED_STRING_ERROR", "method \"{0}\" expected a string argument");
+
+  static final DiagnosticType INVALID_ARGUMENT_ERROR = DiagnosticType.error(
+      "JSC_INVALID_ARGUMENT_ERROR",
+      "method \"{0}\" called with invalid argument");
+
+  static final DiagnosticType INVALID_STYLE_ERROR = DiagnosticType.error(
+      "JSC_INVALID_CSS_NAME_MAP_STYLE_ERROR",
+      "Invalid CSS name map style {0}");
+
+  static final DiagnosticType TOO_MANY_ARGUMENTS_ERROR = DiagnosticType.error(
+      "JSC_TOO_MANY_ARGUMENTS_ERROR",
+      "method \"{0}\" called with more than one argument");
+
+  static final DiagnosticType DUPLICATE_NAMESPACE_ERROR =
+      DiagnosticType.error(
+          "JSC_DUPLICATE_NAMESPACE_ERROR",
+          "namespace \"{0}\" cannot be provided twice\n" //
+              + "Originally provided at {1}");
+
+  static final DiagnosticType WEAK_NAMESPACE_TYPE = DiagnosticType.warning(
+      "JSC_WEAK_NAMESPACE_TYPE",
+      "Provided symbol declared with type Object. This is rarely useful. "
+      + "For more information see "
+      + "https://github.com/google/closure-compiler/wiki/A-word-about-the-type-Object");
+
+  static final DiagnosticType CLASS_NAMESPACE_ERROR = DiagnosticType.error(
+      "JSC_CLASS_NAMESPACE_ERROR",
+    "\"{0}\" cannot be both provided and declared as a class. Try var {0} = class '{'...'}'");
+
+  static final DiagnosticType FUNCTION_NAMESPACE_ERROR = DiagnosticType.error(
+      "JSC_FUNCTION_NAMESPACE_ERROR",
+      "\"{0}\" cannot be both provided and declared as a function");
+
+  static final DiagnosticType MISSING_PROVIDE_ERROR = DiagnosticType.error(
+      "JSC_MISSING_PROVIDE_ERROR",
+      "required \"{0}\" namespace never provided");
+
+  static final DiagnosticType LATE_PROVIDE_ERROR = DiagnosticType.error(
+      "JSC_LATE_PROVIDE_ERROR",
+      "required \"{0}\" namespace not provided yet");
+
+  static final DiagnosticType INVALID_PROVIDE_ERROR = DiagnosticType.error(
+      "JSC_INVALID_PROVIDE_ERROR",
+      "\"{0}\" is not a valid {1} qualified name");
+
+  static final DiagnosticType INVALID_DEFINE_NAME_ERROR = DiagnosticType.error(
+      "JSC_INVALID_DEFINE_NAME_ERROR",
+      "\"{0}\" is not a valid JS identifier name");
+
+  static final DiagnosticType MISSING_DEFINE_ANNOTATION = DiagnosticType.error(
+      "JSC_INVALID_MISSING_DEFINE_ANNOTATION",
+      "Missing @define annotation");
+
+  static final DiagnosticType XMODULE_REQUIRE_ERROR =
+      DiagnosticType.warning(
+          "JSC_XMODULE_REQUIRE_ERROR",
+          "namespace \"{0}\" is required in module {2} but provided in module {1}."
+              + " Is module {2} missing a dependency on module {1}?");
+
+  static final DiagnosticType NON_STRING_PASSED_TO_SET_CSS_NAME_MAPPING_ERROR =
+      DiagnosticType.error(
+          "JSC_NON_STRING_PASSED_TO_SET_CSS_NAME_MAPPING_ERROR",
+      "goog.setCssNameMapping only takes an object literal with string values");
+
+  static final DiagnosticType INVALID_CSS_RENAMING_MAP = DiagnosticType.warning(
+      "INVALID_CSS_RENAMING_MAP",
+      "Invalid entries in css renaming map: {0}");
+
+  static final DiagnosticType GOOG_BASE_CLASS_ERROR = DiagnosticType.error(
+      "JSC_GOOG_BASE_CLASS_ERROR",
+      "incorrect use of goog.base: {0}");
+
+  static final DiagnosticType BASE_CLASS_ERROR = DiagnosticType.error(
+      "JSC_BASE_CLASS_ERROR",
+      "incorrect use of {0}.base: {1}");
+
+  static final DiagnosticType CLOSURE_DEFINES_ERROR = DiagnosticType.error(
+      "JSC_CLOSURE_DEFINES_ERROR",
+      "Invalid CLOSURE_DEFINES definition");
+
+  static final DiagnosticType INVALID_FORWARD_DECLARE = DiagnosticType.error(
+      "JSC_INVALID_FORWARD_DECLARE",
+      "Malformed goog.forwardDeclaration");
+
+  static final DiagnosticType USE_OF_GOOG_BASE = DiagnosticType.disabled(
+      "JSC_USE_OF_GOOG_BASE",
+      "goog.base is not compatible with ES5 strict mode.\n"
+      + "Please use an alternative.\n"
+      + "For EcmaScript classes use the super keyword. For traditional Closure classes,\n"
+      + "use the class specific base method instead. For example, for the constructor MyClass:\n"
+      + "   MyClass.base(this, ''constructor'')");
+
+  static final DiagnosticType CLOSURE_CALL_CANNOT_BE_ALIASED_ERROR =
+      DiagnosticType.error(
+          "JSC_CLOSURE_CALL_CANNOT_BE_ALIASED_ERROR",
+          "Closure primitive method {0} may not be aliased");
+
+  static final DiagnosticType CLOSURE_CALL_CANNOT_BE_ALIASED_OUTSIDE_MODULE_ERROR =
+      DiagnosticType.error(
+          "JSC_CLOSURE_CALL_CANNOT_BE_ALIASED_ERROR",
+          "Closure primitive method {0} may not be aliased  outside a module (ES "
+              + "module, CommonJS module, or goog.module)");
+
+  /** The root Closure namespace */
+  static final String GOOG = "goog";
+
+  private final AbstractCompiler compiler;
+  private final JSModuleGraph moduleGraph;
+
+  // The goog.provides must be processed in a deterministic order.
+  private final Map<String, ProvidedName> providedNames = new LinkedHashMap<String, ProvidedName>();
+
+  private final Set<String> knownClosureSubclasses = new HashSet<String>();
+
+  private final List<UnrecognizedRequire> unrecognizedRequires = new ArrayList<UnrecognizedRequire>();
+  private final Set<String> exportedVariables = new HashSet<String>();
+  private final CheckLevel requiresLevel;
+  private final PreprocessorSymbolTable preprocessorSymbolTable;
+  private final List<Node> defineCalls = new ArrayList<Node>();
+  private final boolean preserveGoogProvidesAndRequires;
+  private final List<Node> requiresToBeRemoved = new ArrayList<Node>();
+  private final Set<Node> maybeTemporarilyLiveNodes = new HashSet<Node>();
+
+  ProcessClosurePrimitivesWithModuleSupport(AbstractCompiler compiler,
+      @Nullable PreprocessorSymbolTable preprocessorSymbolTable,
+      CheckLevel requiresLevel,
+      boolean preserveGoogProvidesAndRequires) {
+    this.compiler = compiler;
+    this.preprocessorSymbolTable = preprocessorSymbolTable;
+    this.moduleGraph = compiler.getModuleGraph();
+    this.requiresLevel = requiresLevel;
+    this.preserveGoogProvidesAndRequires = preserveGoogProvidesAndRequires;
+
+    // goog is special-cased because it is provided in Closure's base library.
+    providedNames.put(GOOG,
+        new ProvidedName(GOOG, null, null, false /* implicit */));
+  }
+
+  Set<String> getExportedVariableNames() {
+    return exportedVariables;
+  }
+  
+  /** list of strings from the externs */
+  private ArrayList<String> externStrings = new ArrayList<String>();
+
+  /** a map extern node trees to their list of vars that are in the externs but also renamed/aliased */
+  public static WeakHashMap<Node, List<String>> externedAliases = new WeakHashMap<Node, List<String>>();
+  
+  /** list of namespaces that are in the externs but also renamed/aliased */
+  private ArrayList<String> externAliases = new ArrayList<String>();
+  
+  /** a map extern node trees to the processed goog.provides */
+  public static WeakHashMap<Node, List<String>> providedsMap = new WeakHashMap<Node, List<String>>();
+  
+  /** list of namespaces that are goog.provided */
+  private ArrayList<String> provideds = new ArrayList<String>();
+  
+  @Override
+  public void process(Node externs, Node root) {
+    /*
+     * ApacheRoyale:  build list of namespaces from externs 
+     */
+    GlobalNamespace externNamespace = new GlobalNamespace(compiler, externs);
+    List<Name> externNames = externNamespace.getNameForest();
+    for (Name en : externNames) {
+      addExternNameAndDescendants(en, externStrings);
+    }
+    externedAliases.put(externs, externAliases);
+    providedsMap.put(externs, provideds);
+    
+    NodeTraversal.traverseRoots(compiler, this, externs, root);
+
+    for (Node n : defineCalls) {
+      replaceGoogDefines(n);
+    }
+
+    for (ProvidedName pn : providedNames.values()) {
+      pn.replace();
+    }
+
+    if (requiresLevel.isOn()) {
+      for (UnrecognizedRequire r : unrecognizedRequires) {
+        checkForLateOrMissingProvide(r);
+      }
+    }
+
+    for (Node closureRequire : requiresToBeRemoved) {
+      compiler.reportChangeToEnclosingScope(closureRequire);
+      closureRequire.detach();
+    }
+    for (Node liveNode : maybeTemporarilyLiveNodes) {
+      compiler.reportChangeToEnclosingScope(liveNode);
+    }
+  }
+
+  private void checkForLateOrMissingProvide(UnrecognizedRequire r) {
+    // Both goog.require and goog.requireType must have a matching goog.provide.
+    // However, goog.require must match an earlier goog.provide, while goog.requireType is allowed
+    // to match a later goog.provide.
+    DiagnosticType error;
+    ProvidedName expectedName = providedNames.get(r.namespace);
+    if (expectedName != null && expectedName.firstNode != null) {
+      if (r.isRequireType) {
+        return;
+      }
+      error = LATE_PROVIDE_ERROR;
+    } else {
+      error = MISSING_PROVIDE_ERROR;
+    }
+    compiler.report(JSError.make(r.requireNode, requiresLevel, error, r.namespace));
+  }
+
+  private Node getAnyValueOfType(JSDocInfo jsdoc) {
+    checkArgument(jsdoc.hasType());
+    Node typeAst = jsdoc.getType().getRoot();
+    if (typeAst.getToken() == Token.BANG) {
+      typeAst = typeAst.getLastChild();
+    }
+    checkState(typeAst.isString(), typeAst);
+    /** Converted switch to else/if for Java 1.6 compatibility */
+    String astType = typeAst.getString();
+    if (astType.contentEquals("boolean"))
+        return IR.falseNode();
+    if (astType.contentEquals("string"))
+        return IR.string("");
+    if (astType.contentEquals("number"))
+        return IR.number(0);
+    
+    throw new RuntimeException(typeAst.getString());
+  }
+
+  /**
+   * @param n
+   */
+  private void replaceGoogDefines(Node n) {
+    Node parent = n.getParent();
+    checkState(parent.isExprResult());
+    String name = n.getSecondChild().getString();
+    JSDocInfo jsdoc = n.getJSDocInfo();
+    Node value =
+        n.isFromExterns() ? getAnyValueOfType(jsdoc).srcref(n) : n.getChildAtIndex(2).detach();
+
+    Node replacement = NodeUtil.newQNameDeclaration(compiler, name, value, jsdoc);
+    replacement.useSourceInfoIfMissingFromForTree(parent);
+    parent.replaceWith(replacement);
+    compiler.reportChangeToEnclosingScope(replacement);
+  }
+
+  @Override
+  public void hotSwapScript(Node scriptRoot, Node originalRoot) {
+    // TODO(bashir): Implement a real hot-swap version instead and make it fully
+    // consistent with the full version.
+    this.compiler.process(this);
+  }
+
+  @Override
+  public void visit(NodeTraversal t, Node n, Node parent) {
+    switch (n.getToken()) {
+      case CALL:
+        Node left = n.getFirstChild();
+        if (left.isGetProp()) {
+          Node name = left.getFirstChild();
+          if (name.isName() && GOOG.equals(name.getString())) {
+            // For the sake of simplicity, we report code changes
+            // when we see a provides/requires, and don't worry about
+            // reporting the change when we actually do the replacement.
+            String methodName = name.getNext().getString();
+            /** Converted switch to else/if for Java 1.6 compatibility */
+            if (methodName.contentEquals("base"))
+                processBaseClassCall(t, n);
+            else if (methodName.contentEquals("define"))
+            {
+                if (validateUnaliasablePrimitiveCall(t, n, methodName)) {
+                  processDefineCall(t, n, parent);
+                }
+            }
+            else if (methodName.contentEquals("require") ||
+            		methodName.contentEquals("requireType"))
+            {
+                if (validateAliasiablePrimitiveCall(t, n, methodName)) {
+                  processRequireCall(t, n, parent);
+                }
+            }
+            else if (methodName.contentEquals("provide"))
+            {
+                if (validateUnaliasablePrimitiveCall(t, n, methodName)) {
+                  processProvideCall(t, n, parent);
+                }
+            }
+            else if (methodName.contentEquals("inherits"))
+                processInheritsCall(n);
+            else if (methodName.contentEquals("exportSymbol"))
+            {
+                // Note: exportSymbol is allowed in local scope
+                Node arg = left.getNext();
+                if (arg.isString()) {
+                  String argString = arg.getString();
+                  int dot = argString.indexOf('.');
+                  if (dot == -1) {
+                    exportedVariables.add(argString);
+                  } else {
+                    exportedVariables.add(argString.substring(0, dot));
+                  }
+                }
+            }
+            else if (methodName.contentEquals("forwardDeclare"))
+            {
+                if (validateAliasiablePrimitiveCall(t, n, methodName)) {
+                  processForwardDeclare(t, n, parent);
+                }
+            }
+            else if (methodName.contentEquals("addDependency"))
+            {
+                if (validateUnaliasablePrimitiveCall(t, n, methodName)) {
+                  processAddDependency(n, parent);
+                }
+            }
+            else if (methodName.contentEquals("setCssNameMapping")) {
+                processSetCssNameMapping(t, n, parent);
+            }
+          } else if (left.getLastChild().getString().equals("base")) {
+            // maybe an "base" setup by goog.inherits
+            maybeProcessClassBaseCall(t, n);
+          }
+        }
+        break;
+
+      case ASSIGN:
+      case NAME:
+        if (n.isName() && n.getString().equals("CLOSURE_DEFINES")) {
+          handleClosureDefinesValues(t, n);
+        } else {
+          // If this is an assignment to a provided name, remove the provided
+          // object.
+          handleCandidateProvideDefinition(t, n, parent);
+        }
+        break;
+
+      case EXPR_RESULT:
+        handleStubDefinition(t, n);
+        break;
+
+      case CLASS:
+        if (t.inGlobalHoistScope() && !NodeUtil.isClassExpression(n)) {
+          String name = n.getFirstChild().getString();
+          ProvidedName pn = providedNames.get(name);
+          if (pn != null) {
+            compiler.report(t.makeError(n, CLASS_NAMESPACE_ERROR, name));
+          }
+        }
+        break;
+
+      case FUNCTION:
+        // If this is a declaration of a provided named function, this is an
+        // error. Hoisted functions will explode if they're provided.
+        if (t.inGlobalHoistScope() && NodeUtil.isFunctionDeclaration(n)) {
+          String name = n.getFirstChild().getString();
+          ProvidedName pn = providedNames.get(name);
+          if (pn != null) {
+            compiler.report(t.makeError(n, FUNCTION_NAMESPACE_ERROR, name));
+          }
+        }
+        break;
+
+      case GETPROP:
+        if (n.getFirstChild().isName()
+            && !parent.isCall()
+            && !parent.isAssign()
+            && n.matchesQualifiedName("goog.base")
+            && !n.getSourceFileName().endsWith("goog.js")) {
+          reportBadGoogBaseUse(t, n, "May only be called directly.");
+        }
+        break;
+      default:
+        break;
+    }
+  }
+
+  /**
+   * Verifies that a) the call is in the global scope and b) the return value is unused
+   *
+   * <p>This method is for primitives that never return a value.
+   */
+  private boolean validateUnaliasablePrimitiveCall(NodeTraversal t, Node n, String methodName) {
+    return validatePrimitiveCallWithMessage(t, n, methodName, CLOSURE_CALL_CANNOT_BE_ALIASED_ERROR);
+  }
+
+  /**
+   * Verifies that a) the call is in the global scope and b) the return value is unused
+   *
+   * <p>This method is for primitives that do return a value in modules, but not in scripts/
+   * goog.provide files
+   */
+  private boolean validateAliasiablePrimitiveCall(NodeTraversal t, Node n, String methodName) {
+    return validatePrimitiveCallWithMessage(
+        t, n, methodName, CLOSURE_CALL_CANNOT_BE_ALIASED_OUTSIDE_MODULE_ERROR);
+  }
+
+  /**
+   * @param methodName list of primitve types classed together with this one
+   * @param invalidAliasingError which DiagnosticType to emit if this call is aliased. this depends
+   *     on whether the primitive is sometimes aliasiable in a module or never aliasable.
+   */
+  private boolean validatePrimitiveCallWithMessage(
+      NodeTraversal t, Node n, String methodName, DiagnosticType invalidAliasingError) {
+    // Ignore invalid primitives if we didn't strip module sugar.
+    if (compiler.getOptions().shouldPreserveGoogModule()) {
+      return true;
+    }
+
+    if (!t.inGlobalHoistScope()) {
+      compiler.report(t.makeError(n, INVALID_CLOSURE_CALL_SCOPE_ERROR));
+      return false;
+    } else if (!n.getParent().isExprResult()) {
+      // If the call is in the global hoist scope, but the result is used
+      compiler.report(t.makeError(n, invalidAliasingError, GOOG + "." + methodName));
+      return false;
+    }
+    return true;
+  }
+
+  private void handleClosureDefinesValues(NodeTraversal t, Node n) {
+    // var CLOSURE_DEFINES = {};
+    if (NodeUtil.isNameDeclaration(n.getParent())
+        && n.hasOneChild()
+        && n.getFirstChild().isObjectLit()) {
+      HashMap<String, Node> builder = new HashMap<String, Node>();
+      builder.putAll(compiler.getDefaultDefineValues());
+      for (Node c : n.getFirstChild().children()) {
+        if (c.isStringKey()
+            && c.getFirstChild() != null  // Shorthand assignment
+            && isValidDefineValue(c.getFirstChild())) {
+          builder.put(c.getString(), c.getFirstChild().cloneTree());
+        } else {
+          reportBadClosureCommonDefinesDefinition(t, c);
+        }
+      }
+      compiler.setDefaultDefineValues(ImmutableMap.copyOf(builder));
+    }
+  }
+
+  static boolean isValidDefineValue(Node val) {
+    switch (val.getToken()) {
+      case STRING:
+      case NUMBER:
+      case TRUE:
+      case FALSE:
+        return true;
+      case NEG:
+        return val.getFirstChild().isNumber();
+      default:
+        return false;
+    }
+  }
+
+  /** Handles a goog.require or goog.requireType call. */
+  private void processRequireCall(NodeTraversal t, Node n, Node parent) {
+    Node left = n.getFirstChild();
+    Node arg = left.getNext();
+    String method = left.getFirstChild().getNext().getString();
+    if (verifyLastArgumentIsString(t, left, arg)) {
+      String ns = arg.getString();
+      ProvidedName provided = providedNames.get(ns);
+      if (provided == null || !provided.isExplicitlyProvided()) {
+        unrecognizedRequires.add(new UnrecognizedRequire(n, ns, method.equals("requireType")));
+      } else {
+        JSModule providedModule = provided.explicitModule;
+
+        if (!provided.isFromExterns()) {
+          // TODO(tbreisacher): Report an error if there's a goog.provide in an @externs file.
+          checkNotNull(providedModule, n);
+
+          JSModule module = t.getModule();
+          // A cross-chunk goog.require must match a goog.provide in an earlier chunk. However, a
+          // cross-chunk goog.requireType is allowed to match a goog.provide in a later chunk.
+          if (module != providedModule
+              && !moduleGraph.dependsOn(module, providedModule)
+              && !method.equals("requireType")) {
+            compiler.report(
+                t.makeError(n, XMODULE_REQUIRE_ERROR, ns,
+                    providedModule.getName(),
+                    module.getName()));
+          }
+        }
+      }
+
+      maybeAddToSymbolTable(left);
+      maybeAddStringNodeToSymbolTable(arg);
+
+      // Requires should be removed before further processing.
+      // Some clients run closure pass multiple times, first with
+      // the checks for broken requires turned off. In these cases, we
+      // allow broken requires to be preserved by the first run to
+      // let them be caught in the subsequent run.
+      if (!preserveGoogProvidesAndRequires && (provided != null || requiresLevel.isOn())) {
+        requiresToBeRemoved.add(parent);
+      }
+    }
+  }
+
+  /**
+   * Handles a goog.provide call.
+   */
+  private void processProvideCall(NodeTraversal t, Node n, Node parent) {
+    checkState(n.isCall());
+    Node left = n.getFirstChild();
+    Node arg = left.getNext();
+    if (verifyProvide(t, left, arg)) {
+      String ns = arg.getString();
+
+      maybeAddToSymbolTable(left);
+      maybeAddStringNodeToSymbolTable(arg);
+
+      if (providedNames.containsKey(ns)) {
+        ProvidedName previouslyProvided = providedNames.get(ns);
+        if (!previouslyProvided.isExplicitlyProvided()) {
+          previouslyProvided.addProvide(parent, t.getModule(), true);
+        } else {
+          String explicitSourceName = previouslyProvided.explicitNode.getSourceFileName();
+          compiler.report(t.makeError(n, DUPLICATE_NAMESPACE_ERROR, ns, explicitSourceName));
+        }
+      } else {
+        registerAnyProvidedPrefixes(ns, parent, t.getModule());
+        providedNames.put(
+            ns, new ProvidedName(ns, parent, t.getModule(), true));
+      }
+    }
+  }
+
+  /**
+   * Handles a goog.define call.
+   */
+  private void processDefineCall(NodeTraversal t, Node n, Node parent) {
+    Node left = n.getFirstChild();
+    Node args = left.getNext();
+    if (verifyDefine(t, parent, left, args)) {
+      Node nameNode = args;
+
+      maybeAddToSymbolTable(left);
+      maybeAddStringNodeToSymbolTable(nameNode);
+
+      this.defineCalls.add(n);
+    }
+  }
+
+  /**
+   * Handles a stub definition for a goog.provided name
+   * (e.g. a @typedef or a definition from externs)
+   *
+   * @param n EXPR_RESULT node.
+   */
+  private void handleStubDefinition(NodeTraversal t, Node n) {
+    if (!t.inGlobalHoistScope()) {
+      return;
+    }
+    JSDocInfo info = n.getFirstChild().getJSDocInfo();
+    boolean hasStubDefinition = info != null && (n.isFromExterns() || info.hasTypedefType());
+    if (hasStubDefinition) {
+      if (n.getFirstChild().isQualifiedName()) {
+        String name = n.getFirstChild().getQualifiedName();
+        ProvidedName pn = providedNames.get(name);
+        if (pn != null) {
+          n.putBooleanProp(Node.WAS_PREVIOUSLY_PROVIDED, true);
+          pn.addDefinition(n, t.getModule());
+        } else if (n.getBooleanProp(Node.WAS_PREVIOUSLY_PROVIDED)) {
+          // We didn't find it in the providedNames, but it was previously marked as provided.
+          // This implies we're in hotswap pass and the current typedef is a provided namespace.
+          ProvidedName provided = new ProvidedName(name, n, t.getModule(), true);
+          providedNames.put(name, provided);
+        }
+      }
+    }
+  }
+
+  /**
+   * Handles a candidate definition for a goog.provided name.
+   */
+  private void handleCandidateProvideDefinition(
+      NodeTraversal t, Node n, Node parent) {
+    if (t.inGlobalHoistScope()) {
+      String name = null;
+      if (n.isName() && NodeUtil.isNameDeclaration(parent)) {
+        name = n.getString();
+      } else if (n.isAssign() && parent.isExprResult()) {
+        name = n.getFirstChild().getQualifiedName();
+      }
+
+      if (name != null) {
+        if (parent.getBooleanProp(Node.IS_NAMESPACE)) {
+          processProvideFromPreviousPass(t, name, parent);
+        } else {
+          ProvidedName pn = providedNames.get(name);
+          if (pn != null) {
+            pn.addDefinition(parent, t.getModule());
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Processes the base class call.
+   */
+  private void processBaseClassCall(NodeTraversal t, Node n) {
+    // Two things must hold for every goog.base call:
+    // 1) We must be calling it on "this".
+    // 2) We must be calling it on a prototype method of the same name as
+    //    the one we're in, OR we must be calling it from a constructor.
+    // If both of those things are true, then we can rewrite:
+    // <pre>
+    // function Foo() {
+    //   goog.base(this);
+    // }
+    // goog.inherits(Foo, BaseFoo);
+    // Foo.prototype.bar = function() {
+    //   goog.base(this, 'bar', 1);
+    // };
+    // </pre>
+    // as the easy-to-optimize:
+    // <pre>
+    // function Foo() {
+    //   BaseFoo.call(this);
+    // }
+    // goog.inherits(Foo, BaseFoo);
+    // Foo.prototype.bar = function() {
+    //   Foo.superClass_.bar.call(this, 1);
+    // };
+    //
+    // Most of the logic here is just to make sure the AST's
+    // structure is what we expect it to be.
+
+    // If requested report uses of goog.base.
+    t.report(n, USE_OF_GOOG_BASE);
+
+    if (baseUsedInClass(n)){
+      reportBadGoogBaseUse(t, n, "goog.base in ES6 class is not allowed. Use super instead.");
+      return;
+    }
+
+    Node callee = n.getFirstChild();
+    Node thisArg = callee.getNext();
+    if (thisArg == null || !thisArg.isThis()) {
+      reportBadGoogBaseUse(t, n, "First argument must be 'this'.");
+      return;
+    }
+
+    Node enclosingFnNameNode = getEnclosingDeclNameNode(n);
+    if (enclosingFnNameNode == null) {
+      reportBadGoogBaseUse(t, n, "Could not find enclosing method.");
+      return;
+    }
+
+    String enclosingQname = enclosingFnNameNode.getQualifiedName();
+    if (!enclosingQname.contains(".prototype.")) {
+      // Handle constructors.
+      Node enclosingParent = enclosingFnNameNode.getParent();
+      Node maybeInheritsExpr =
+          (enclosingParent.isAssign() ? enclosingParent.getParent() : enclosingParent).getNext();
+      Node baseClassNode = null;
+      if (maybeInheritsExpr != null
+          && maybeInheritsExpr.isExprResult()
+          && maybeInheritsExpr.getFirstChild().isCall()) {
+        Node callNode = maybeInheritsExpr.getFirstChild();
+        if (callNode.getFirstChild().matchesQualifiedName("goog.inherits")
+            && callNode.getLastChild().isQualifiedName()) {
+          baseClassNode = callNode.getLastChild();
+        }
+      }
+
+      if (baseClassNode == null) {
+        reportBadGoogBaseUse(
+            t, n, "Could not find goog.inherits for base class");
+        return;
+      }
+
+      // We're good to go.
+      Node newCallee =
+          NodeUtil.newQName(
+              compiler, baseClassNode.getQualifiedName() + ".call", callee, "goog.base");
+      n.replaceChild(callee, newCallee);
+      compiler.reportChangeToEnclosingScope(newCallee);
+    } else {
+      // Handle methods.
+      Node methodNameNode = thisArg.getNext();
+      if (methodNameNode == null || !methodNameNode.isString()) {
+        reportBadGoogBaseUse(t, n, "Second argument must name a method.");
+        return;
+      }
+
+      String methodName = methodNameNode.getString();
+      String ending = ".prototype." + methodName;
+      if (enclosingQname == null || !enclosingQname.endsWith(ending)) {
+        reportBadGoogBaseUse(
+            t, n, "Enclosing method does not match " + methodName);
+        return;
+      }
+
+      // We're good to go.
+      Node className =
+          enclosingFnNameNode.getFirstFirstChild();
+      n.replaceChild(
+          callee,
+          NodeUtil.newQName(
+            compiler,
+            className.getQualifiedName() + ".superClass_." + methodName + ".call",
+            callee, "goog.base"));
+      n.removeChild(methodNameNode);
+      compiler.reportChangeToEnclosingScope(n);
+    }
+  }
+
+  private void maybeProcessClassBaseCall(NodeTraversal t, Node n) {
+    // Two things must hold for every base call:
+    // 1) We must be calling it on "this".
+    // 2) We must be calling it on a prototype method of the same name as
+    //    the one we're in, OR we must be calling it from a constructor.
+    // If both of those things are true, then we can rewrite:
+    // <pre>
+    // function Foo() {
+    //   Foo.base(this);
+    // }
+    // goog.inherits(Foo, BaseFoo);
+    // Foo.prototype.bar = function() {
+    //   Foo.base(this, 'bar', 1);
+    // };
+    // </pre>
+    // as the easy-to-optimize:
+    // <pre>
+    // function Foo() {
+    //   BaseFoo.call(this);
+    // }
+    // goog.inherits(Foo, BaseFoo);
+    // Foo.prototype.bar = function() {
+    //   Foo.superClass_.bar.call(this, 1);
+    // };
+    //
+    // Most of the logic here is just to make sure the AST's
+    // structure is what we expect it to be.
+
+    Node callTarget = n.getFirstChild();
+    Node baseContainerNode = callTarget.getFirstChild();
+    if (!baseContainerNode.isUnscopedQualifiedName()) {
+      // Some unknown "base" method.
+      return;
+    }
+    String baseContainer = callTarget.getFirstChild().getQualifiedName();
+
+    Node enclosingFnNameNode = getEnclosingDeclNameNode(n);
+    if (enclosingFnNameNode == null || !enclosingFnNameNode.isUnscopedQualifiedName()) {
+      // some unknown container method.
+      if (knownClosureSubclasses.contains(baseContainer)) {
+        reportBadBaseMethodUse(t, n, baseContainer, "Could not find enclosing method.");
+      } else if (baseUsedInClass(n)) {
+        Node clazz = NodeUtil.getEnclosingClass(n);
+        if ((clazz.getFirstChild().isName()
+                && clazz.getFirstChild().getString().equals(baseContainer))
+            || (clazz.getSecondChild().isName()
+                && clazz.getSecondChild().getString().equals(baseContainer))) {
+          reportBadBaseMethodUse(t, n, clazz.getFirstChild().getString(),
+              "base method is not allowed in ES6 class. Use super instead.");
+        }
+      }
+      return;
+    }
+
+    if (baseUsedInClass(n)) {
+      reportBadGoogBaseUse(t, n, "goog.base in ES6 class is not allowed. Use super instead.");
+      return;
+    }
+
+    String enclosingQname = enclosingFnNameNode.getQualifiedName();
+    if (!enclosingQname.contains(".prototype.")) {
+      // Handle constructors.
+
+      // Check if this is some other "base" method.
+      if (!enclosingQname.equals(baseContainer)) {
+        // Report misuse of "base" methods from other known classes.
+        if (knownClosureSubclasses.contains(baseContainer)) {
+          reportBadBaseMethodUse(t, n, baseContainer, "Must be used within "
+              + baseContainer + " methods");
+        }
+        return;
+      }
+
+      // Determine if this is a class with a "base" method created by
+      // goog.inherits.
+      Node enclosingParent = enclosingFnNameNode.getParent();
+      Node maybeInheritsExpr =
+          (enclosingParent.isAssign() ? enclosingParent.getParent() : enclosingParent).getNext();
+      while (maybeInheritsExpr != null && maybeInheritsExpr.isEmpty()) {
+        maybeInheritsExpr = maybeInheritsExpr.getNext();
+      }
+      Node baseClassNode = null;
+      if (maybeInheritsExpr != null
+          && maybeInheritsExpr.isExprResult()
+          && maybeInheritsExpr.getFirstChild().isCall()) {
+        Node callNode = maybeInheritsExpr.getFirstChild();
+        if (callNode.getFirstChild().matchesQualifiedName("goog.inherits")
+            && callNode.getLastChild().isQualifiedName()) {
+          baseClassNode = callNode.getLastChild();
+        }
+      }
+
+      if (baseClassNode == null) {
+        // If there is no "goog.inherits", this might be some other "base"
+        // method.
+        return;
+      }
+
+      // This is the expected method, validate its parameters.
+      Node callee = n.getFirstChild();
+      Node thisArg = callee.getNext();
+      if (thisArg == null || !thisArg.isThis()) {
+        reportBadBaseMethodUse(t, n, baseContainer,
+            "First argument must be 'this'.");
+        return;
+      }
+
+      // Handle methods.
+      Node methodNameNode = thisArg.getNext();
+      if (methodNameNode == null
+          || !methodNameNode.isString()
+          || !methodNameNode.getString().equals("constructor")) {
+        reportBadBaseMethodUse(t, n, baseContainer,
+            "Second argument must be 'constructor'.");
+        return;
+      }
+
+      // We're good to go.
+      n.replaceChild(
+          callee,
+          NodeUtil.newQName(
+            compiler,
+            baseClassNode.getQualifiedName() + ".call",
+            callee, enclosingQname + ".base"));
+      n.removeChild(methodNameNode);
+      compiler.reportChangeToEnclosingScope(n);
+    } else {
+      if (!knownClosureSubclasses.contains(baseContainer)) {
+        // Can't determine if this is a known "class" that has a known "base"
+        // method.
+        return;
+      }
+
+      boolean misuseOfBase = !enclosingFnNameNode.
+          getFirstFirstChild().matchesQualifiedName(baseContainer);
+      if (misuseOfBase) {
+        // Report misuse of "base" methods from other known classes.
+        reportBadBaseMethodUse(t, n, baseContainer, "Must be used within "
+            + baseContainer + " methods");
+        return;
+      }
+
+      // The super class is known.
+      Node callee = n.getFirstChild();
+      Node thisArg = callee.getNext();
+      if (thisArg == null || !thisArg.isThis()) {
+        reportBadBaseMethodUse(t, n, baseContainer,
+            "First argument must be 'this'.");
+        return;
+      }
+
+      // Handle methods.
+      Node methodNameNode = thisArg.getNext();
+      if (methodNameNode == null || !methodNameNode.isString()) {
+        reportBadBaseMethodUse(t, n, baseContainer,
+            "Second argument must name a method.");
+        return;
+      }
+
+      String methodName = methodNameNode.getString();
+      String ending = ".prototype." + methodName;
+      if (enclosingQname == null || !enclosingQname.endsWith(ending)) {
+        reportBadBaseMethodUse(t, n, baseContainer,
+            "Enclosing method does not match " + methodName);
+        return;
+      }
+
+      // We're good to go.
+      Node className =
+          enclosingFnNameNode.getFirstFirstChild();
+      n.replaceChild(
+          callee,
+          NodeUtil.newQName(
+            compiler,
+            className.getQualifiedName() + ".superClass_." + methodName + ".call",
+            callee, enclosingQname + ".base"));
+      n.removeChild(methodNameNode);
+      compiler.reportChangeToEnclosingScope(n);
+    }
+  }
+
+  /**
+   * Processes the goog.inherits call.
+   */
+  private void processInheritsCall(Node n) {
+    if (n.getChildCount() == 3) {
+      Node subClass = n.getSecondChild();
+      Node superClass = subClass.getNext();
+      if (subClass.isUnscopedQualifiedName() && superClass.isUnscopedQualifiedName()) {
+        knownClosureSubclasses.add(subClass.getQualifiedName());
+      }
+    }
+  }
+
+  /**
+   * Returns the qualified name node of the function whose scope we're in,
+   * or null if it cannot be found.
+   */
+  private static Node getEnclosingDeclNameNode(Node n) {
+    Node fn = NodeUtil.getEnclosingFunction(n);
+    return fn == null ? null : NodeUtil.getNameNode(fn);
+  }
+
+  /** Verify if goog.base call is used in a class */
+  private boolean baseUsedInClass(Node n){
+    for (Node curr = n; curr != null; curr = curr.getParent()){
+      if (curr.isClassMembers()) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /** Reports an incorrect use of super-method calling. */
+  private void reportBadGoogBaseUse(
+      NodeTraversal t, Node n, String extraMessage) {
+    compiler.report(t.makeError(n, GOOG_BASE_CLASS_ERROR, extraMessage));
+  }
+
+  /** Reports an incorrect use of super-method calling. */
+  private void reportBadBaseMethodUse(
+      NodeTraversal t, Node n, String className, String extraMessage) {
+    compiler.report(t.makeError(n, BASE_CLASS_ERROR, className, extraMessage));
+  }
+
+  /** Reports an incorrect CLOSURE_DEFINES definition. */
+  private void reportBadClosureCommonDefinesDefinition(
+      NodeTraversal t, Node n) {
+    compiler.report(t.makeError(n, CLOSURE_DEFINES_ERROR));
+  }
+
+  /**
+   * Processes the output of processed-provide from a previous pass.  This will
+   * update our data structures in the same manner as if the provide had been
+   * processed in this pass.
+   */
+  private void processProvideFromPreviousPass(
+      NodeTraversal t, String name, Node parent) {
+    if (!providedNames.containsKey(name)) {
+      // Record this provide created on a previous pass, and create a dummy
+      // EXPR node as a placeholder to simulate an explicit provide.
+      Node expr = new Node(Token.EXPR_RESULT);
+      expr.useSourceInfoIfMissingFromForTree(parent);
+      parent.getParent().addChildBefore(expr, parent);
+      /**
+       * 'expr' has been newly added to the AST, but it might be removed again before this pass
+       * finishes. Keep it in a list for later change reporting if it doesn't get removed again
+       * before the end of the pass.
+       */
+      maybeTemporarilyLiveNodes.add(expr);
+
+      JSModule module = t.getModule();
+      registerAnyProvidedPrefixes(name, expr, module);
+
+      // If registerAnyProvidedPrefixes didn't add any children, add a no-op child so that
+      // the AST is valid.
+      if (!expr.hasChildren()) {
+        expr.addChildToBack(NodeUtil.newUndefinedNode(parent));
+      }
+
+      ProvidedName provided = new ProvidedName(name, expr, module, true);
+      providedNames.put(name, provided);
+      provided.addDefinition(parent, module);
+    } else {
+      // Remove this provide if it came from a previous pass since we have an
+      // replacement already.
+      if (isNamespacePlaceholder(parent)) {
+        compiler.reportChangeToEnclosingScope(parent);
+        parent.detach();
+      }
+    }
+  }
+
+  /**
+   * Processes a call to goog.setCssNameMapping(). Either the argument to
+   * goog.setCssNameMapping() is valid, in which case it will be used to create
+   * a CssRenamingMap for the compiler of this CompilerPass, or it is invalid
+   * and a JSCompiler error will be reported.
+   * @see #visit(NodeTraversal, Node, Node)
+   */
+  private void processSetCssNameMapping(NodeTraversal t, Node n, Node parent) {
+    Node left = n.getFirstChild();
+    Node arg = left.getNext();
+    if (verifySetCssNameMapping(t, left, arg)) {
+      // Translate OBJECTLIT into SubstitutionMap. All keys and
+      // values must be strings, or an error will be thrown.
+      final Map<String, String> cssNames = new HashMap<String, String>();
+
+      for (Node key = arg.getFirstChild(); key != null;
+          key = key.getNext()) {
+        Node value = key.getFirstChild();
+        if (!key.isStringKey()
+            || value == null
+            || !value.isString()) {
+          compiler.report(
+              t.makeError(n,
+                  NON_STRING_PASSED_TO_SET_CSS_NAME_MAPPING_ERROR));
+          return;
+        }
+        cssNames.put(key.getString(), value.getString());
+      }
+
+      String styleStr = "BY_PART";
+      if (arg.getNext() != null) {
+        styleStr = arg.getNext().getString();
+      }
+
+      final CssRenamingMap.Style style;
+      try {
+        style = CssRenamingMap.Style.valueOf(styleStr);
+      } catch (IllegalArgumentException e) {
+        compiler.report(
+            t.makeError(n, INVALID_STYLE_ERROR, styleStr));
+        return;
+      }
+
+      if (style == CssRenamingMap.Style.BY_PART) {
+        // Make sure that no keys contain -'s
+        List<String> errors = new ArrayList<String>();
+        for (String key : cssNames.keySet()) {
+          if (key.contains("-")) {
+            errors.add(key);
+          }
+        }
+        if (!errors.isEmpty()) {
+          compiler.report(
+            t.makeError(n, INVALID_CSS_RENAMING_MAP, errors.toString()));
+        }
+      } else if (style == CssRenamingMap.Style.BY_WHOLE) {
+        // Verifying things is a lot trickier here. We just do a quick
+        // n^2 check over the map which makes sure that if "a-b" in
+        // the map, then map(a-b) = map(a)-map(b).
+        // To speed things up, only consider cases where len(b) <= 10
+        List<String> errors = new ArrayList<String>();
+        for (Map.Entry<String, String> b : cssNames.entrySet()) {
+          if (b.getKey().length() > 10) {
+            continue;
+          }
+          for (Map.Entry<String, String> a : cssNames.entrySet()) {
+            String combined = cssNames.get(a.getKey() + "-" + b.getKey());
+            if (combined != null && !combined.equals(a.getValue() + "-" + b.getValue())) {
+              errors.add("map(" + a.getKey() + "-" + b.getKey() + ") != map("
+                  + a.getKey() + ")-map(" + b.getKey() + ")");
+            }
+          }
+        }
+        if (!errors.isEmpty()) {
+          compiler.report(
+            t.makeError(n, INVALID_CSS_RENAMING_MAP, errors.toString()));
+        }
+      }
+
+      @SuppressWarnings("serial")
+      CssRenamingMap cssRenamingMap = new CssRenamingMap() {
+        @Override
+        public String get(String value) {
+          if (cssNames.containsKey(value)) {
+            return cssNames.get(value);
+          } else {
+            return value;
+          }
+        }
+
+        @Override
+        public CssRenamingMap.Style getStyle() {
+          return style;
+        }
+      };
+      compiler.setCssRenamingMap(cssRenamingMap);
+      compiler.reportChangeToEnclosingScope(parent);
+      parent.detach();
+    }
+  }
+
+  /**
+   * Verifies that a provide method call has exactly one argument,
+   * and that it's a string literal and that the contents of the string are
+   * valid JS tokens. Reports a compile error if it doesn't.
+   *
+   * @return Whether the argument checked out okay
+   */
+  private boolean verifyProvide(NodeTraversal t, Node methodName, Node arg) {
+    if (!verifyLastArgumentIsString(t, methodName, arg)) {
+      return false;
+    }
+
+    if (!NodeUtil.isValidQualifiedName(
+        compiler.getOptions().getLanguageIn().toFeatureSet(), arg.getString())) {
+      compiler.report(t.makeError(arg, INVALID_PROVIDE_ERROR,
+          arg.getString(), compiler.getOptions().getLanguageIn().toString()));
+      return false;
+    }
+
+    return true;
+  }
+
+  /**
+   * Verifies that a provide method call has exactly one argument,
+   * and that it's a string literal and that the contents of the string are
+   * valid JS tokens. Reports a compile error if it doesn't.
+   *
+   * @return Whether the argument checked out okay
+   */
+  private boolean verifyDefine(NodeTraversal t,
+      Node expr,
+      Node methodName, Node args) {
+
+    // Verify first arg
+    Node arg = args;
+    if (!verifyNotNull(t, methodName, arg) || !verifyOfType(t, methodName, arg, Token.STRING)) {
+      return false;
+    }
+
+    // Verify second arg
+    arg = arg.getNext();
+    if (!args.isFromExterns()
+        && (!verifyNotNull(t, methodName, arg) || !verifyIsLast(t, methodName, arg))) {
+      return false;
+    }
+
+    String name = args.getString();
+    if (!NodeUtil.isValidQualifiedName(
+        compiler.getOptions().getLanguageIn().toFeatureSet(), name)) {
+      compiler.report(t.makeError(args, INVALID_DEFINE_NAME_ERROR, name));
+      return false;
+    }
+
+    JSDocInfo info = expr.getFirstChild().getJSDocInfo();
+    if (info == null || !info.isDefine()) {
+      compiler.report(t.makeError(expr, MISSING_DEFINE_ANNOTATION));
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Process a goog.addDependency() call and record any forward declarations.
+   */
+  private void processAddDependency(Node n, Node parent) {
+    CodingConvention convention = compiler.getCodingConvention();
+    List<String> typeDecls =
+        convention.identifyTypeDeclarationCall(n);
+
+    // TODO(nnaze): Use of addDependency() should someday cause a warning
+    // as we migrate users to explicit goog.forwardDeclare() calls.
+    if (typeDecls != null) {
+      for (String typeDecl : typeDecls) {
+        compiler.forwardDeclareType(typeDecl);
+      }
+    }
+
+    // We can't modify parent, so just create a node that will
+    // get compiled out.
+    Node emptyNode = IR.number(0);
+    parent.replaceChild(n, emptyNode);
+    compiler.reportChangeToEnclosingScope(emptyNode);
+  }
+
+  /**
+   * Process a goog.forwardDeclare() call and record the specified forward
+   * declaration.
+   */
+  private void processForwardDeclare(NodeTraversal t, Node n, Node parent) {
+    CodingConvention convention = compiler.getCodingConvention();
+
+    String typeDeclaration = null;
+    try {
+      typeDeclaration = Iterables.getOnlyElement(
+          convention.identifyTypeDeclarationCall(n));
+    } catch (Exception e) {
+      compiler.report(
+          t.makeError(
+              n,
+              INVALID_FORWARD_DECLARE,
+              "A single type could not identified for the goog.forwardDeclare statement"));
+    }
+
+    if (typeDeclaration != null) {
+      compiler.forwardDeclareType(typeDeclaration);
+      // Forward declaration was recorded and we can remove the call.
+      Node toRemove = parent.isExprResult() ? parent : parent.getParent();
+      NodeUtil.deleteNode(toRemove, compiler);
+    }
+  }
+
+  /**
+   * Verifies that a method call has exactly one argument, and that it's a
+   * string literal. Reports a compile error if it doesn't.
+   *
+   * @return Whether the argument checked out okay
+   */
+  private boolean verifyLastArgumentIsString(
+      NodeTraversal t, Node methodName, Node arg) {
+    return verifyNotNull(t, methodName, arg)
+        && verifyOfType(t, methodName, arg, Token.STRING)
+        && verifyIsLast(t, methodName, arg);
+  }
+
+  /**
+   * @return Whether the argument checked out okay
+   */
+  private boolean verifyNotNull(NodeTraversal t, Node methodName, Node arg) {
+    if (arg == null) {
+      compiler.report(
+          t.makeError(methodName,
+              NULL_ARGUMENT_ERROR, methodName.getQualifiedName()));
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * @return Whether the argument checked out okay
+   */
+  private boolean verifyOfType(NodeTraversal t, Node methodName,
+      Node arg, Token desiredType) {
+    if (arg.getToken() != desiredType) {
+      compiler.report(
+          t.makeError(methodName,
+              INVALID_ARGUMENT_ERROR, methodName.getQualifiedName()));
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * @return Whether the argument checked out okay
+   */
+  private boolean verifyIsLast(NodeTraversal t, Node methodName, Node arg) {
+    if (arg.getNext() != null) {
+      compiler.report(
+          t.makeError(methodName,
+              TOO_MANY_ARGUMENTS_ERROR, methodName.getQualifiedName()));
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Verifies that setCssNameMapping is called with the correct methods.
+   *
+   * @return Whether the arguments checked out okay
+   */
+  private boolean verifySetCssNameMapping(NodeTraversal t, Node methodName,
+      Node firstArg) {
+    DiagnosticType diagnostic = null;
+    if (firstArg == null) {
+      diagnostic = NULL_ARGUMENT_ERROR;
+    } else if (!firstArg.isObjectLit()) {
+      diagnostic = EXPECTED_OBJECTLIT_ERROR;
+    } else if (firstArg.getNext() != null) {
+      Node secondArg = firstArg.getNext();
+      if (!secondArg.isString()) {
+        diagnostic = EXPECTED_STRING_ERROR;
+      } else if (secondArg.getNext() != null) {
+        diagnostic = TOO_MANY_ARGUMENTS_ERROR;
+      }
+    }
+    if (diagnostic != null) {
+      compiler.report(
+          t.makeError(methodName,
+              diagnostic, methodName.getQualifiedName()));
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Build up the list of strings in the externs.
+   * 
+   * @param en The extern name.
+   * @param externStrings The list of strings to add to.
+   */
+  private void addExternNameAndDescendants(Name en, ArrayList<String> externStrings) {
+	    externStrings.add(en.getName());
+
+	    if (en.props == null || en.isCollapsingExplicitlyDenied()) {
+	      return;
+	    }
+	    for (Name p : en.props) {
+	      addExternNameAndDescendants(p, externStrings);
+	    }
+	  }
+
+  /**
+   * Registers ProvidedNames for prefix namespaces if they haven't
+   * already been defined. The prefix namespaces must be registered in
+   * order from shortest to longest.
+   *
+   * @param ns The namespace whose prefixes may need to be provided.
+   * @param node The EXPR of the provide call.
+   * @param module The current module.
+   */
+  private void registerAnyProvidedPrefixes(
+      String ns, Node node, JSModule module) {
+    int pos = ns.indexOf('.');
+    while (pos != -1) {
+      String prefixNs = ns.substring(0, pos);
+      pos = ns.indexOf('.', pos + 1);
+      if (providedNames.containsKey(prefixNs)) {
+        providedNames.get(prefixNs).addProvide(
+            node, module, false /* implicit */);
+      } else {
+        providedNames.put(prefixNs,
+            new ProvidedName(prefixNs, node, module, false /* implicit */));
+        // if it was in externs, added to externAliases
+        if (externStrings.contains(prefixNs))
+          if (!externAliases.contains(prefixNs))
+            externAliases.add(prefixNs);
+        // if the namespace of any provided classes
+        if (!provideds.contains(prefixNs))
+          provideds.add(prefixNs);
+      }
+    }
+  }
+
+  // -------------------------------------------------------------------------
+
+  /**
+   * Information required to replace a goog.provide call later in the traversal.
+   */
+  private class ProvidedName {
+    private final String namespace;
+
+    // The node and module where the call was explicitly or implicitly
+    // goog.provided.
+    private final Node firstNode;
+    private final JSModule firstModule;
+
+    // The node where the call was explicitly goog.provided. May be null
+    // if the namespace is always provided implicitly.
+    private Node explicitNode = null;
+    private JSModule explicitModule = null;
+
+    // There are child namespaces of this one.
+    private boolean hasAChildNamespace = false;
+
+    // The candidate definition.
+    private Node candidateDefinition = null;
+
+    // The minimum module where the provide must appear.
+    private JSModule minimumModule = null;
+
+    // The replacement declaration.
+    private Node replacementNode = null;
+
+    ProvidedName(String namespace, Node node, JSModule module,
+        boolean explicit) {
+      Preconditions.checkArgument(node == null /* The base case */ || node.isExprResult());
+      this.namespace = namespace;
+      this.firstNode = node;
+      this.firstModule = module;
+
+      addProvide(node, module, explicit);
+    }
+
+    /**
+     * Add an implicit or explicit provide.
+     */
+    void addProvide(Node node, JSModule module, boolean explicit) {
+      if (explicit) {
+        // goog.provide('name.space');
+        checkState(explicitNode == null);
+        checkArgument(node.isExprResult());
+        explicitNode = node;
+        explicitModule = module;
+      } else {
+        // goog.provide('name.space.some.child');
+        hasAChildNamespace = true;
+      }
+      updateMinimumModule(module);
+    }
+
+    boolean isExplicitlyProvided() {
+      return explicitNode != null;
+    }
+
+    boolean isFromExterns() {
+      return explicitNode.isFromExterns();
+    }
+
+    /**
+     * Record function declaration, variable declaration or assignment that
+     * refers to the same name as the provide statement.  Give preference to
+     * declarations; if no declaration exists, record a reference to an
+     * assignment so it repurposed later.
+     */
+    void addDefinition(Node node, JSModule module) {
+      Preconditions.checkArgument(
+          node.isExprResult() // assign
+              || node.isFunction()
+              || NodeUtil.isNameDeclaration(node));
+      checkArgument(explicitNode != node);
+      if ((candidateDefinition == null) || !node.isExprResult()) {
+        candidateDefinition = node;
+        updateMinimumModule(module);
+      }
+    }
+
+    private void updateMinimumModule(JSModule newModule) {
+      if (minimumModule == null) {
+        minimumModule = newModule;
+      } else if (moduleGraph.getModuleCount() > 1) {
+        minimumModule = moduleGraph.getDeepestCommonDependencyInclusive(
+            minimumModule, newModule);
+      } else {
+        // If there is no module graph, then there must be exactly one
+        // module in the program.
+        checkState(newModule == minimumModule, "Missing module graph");
+      }
+    }
+
+    /**
+     * Replace the provide statement.
+     *
+     * If we're providing a name with no definition, then create one.
+     * If we're providing a name with a duplicate definition, then make sure
+     * that definition becomes a declaration.
+     */
+    void replace() {
+      if (firstNode == null) {
+        // Don't touch the base case ('goog').
+        replacementNode = candidateDefinition;
+        return;
+      }
+
+      // Handle the case where there is a duplicate definition for an explicitly
+      // provided symbol.
+      if (candidateDefinition != null && explicitNode != null) {
+        JSDocInfo info;
+        if (candidateDefinition.isExprResult()) {
+          info = candidateDefinition.getFirstChild().getJSDocInfo();
+        } else {
+          info = candidateDefinition.getJSDocInfo();
+        }
+
+        // Validate that the namespace is not declared as a generic object type.
+        if (info != null) {
+          JSTypeExpression expr = info.getType();
+          if (expr != null) {
+            Node n = expr.getRoot();
+            if (n.getToken() == Token.BANG) {
+              n = n.getFirstChild();
+            }
+            if (n.isString()
+                && !n.hasChildren() // templated object types are ok.
+                && n.getString().equals("Object")) {
+              compiler.report(
+                  JSError.make(candidateDefinition, WEAK_NAMESPACE_TYPE));
+            }
+          }
+        }
+
+        // Does this need a VAR keyword?
+        replacementNode = candidateDefinition;
+        if (candidateDefinition.isExprResult()) {
+          Node exprNode = candidateDefinition.getOnlyChild();
+          if (exprNode.isAssign()) {
+            // namespace = value;
+            candidateDefinition.putBooleanProp(Node.IS_NAMESPACE, true);
+            Node nameNode = exprNode.getFirstChild();
+            if (nameNode.isName()) {
+              // Need to convert this assign to a var declaration.
+              Node valueNode = nameNode.getNext();
+              exprNode.removeChild(nameNode);
+              exprNode.removeChild(valueNode);
+              nameNode.addChildToFront(valueNode);
+              Node varNode = IR.var(nameNode);
+              varNode.useSourceInfoFrom(candidateDefinition);
+              candidateDefinition.replaceWith(varNode);
+              varNode.setJSDocInfo(exprNode.getJSDocInfo());
+              compiler.reportChangeToEnclosingScope(varNode);
+              replacementNode = varNode;
+            }
+          } else {
+            // /** @typedef {something} */ name.space.Type;
+            checkState(exprNode.isQualifiedName(), exprNode);
+            // If this namespace has child namespaces, we still need to add an object to hang them
+            // on to avoid creating broken code.
+            // We must cast the type of the literal to unknown, because the type checker doesn't
+            // expect the namespace to have a value.
+            if (hasAChildNamespace) {
+              replaceWith(createDeclarationNode(
+                  IR.cast(IR.objectlit(), createUnknownTypeJsDocInfo())));
+            }
+          }
+        }
+      } else {
+        // Handle the case where there's not a duplicate definition.
+        replaceWith(createDeclarationNode(IR.objectlit()));
+      }
+      if (explicitNode != null) {
+        if (preserveGoogProvidesAndRequires && explicitNode.hasChildren()) {
+          return;
+        }
+        /*
+         * If 'explicitNode' was added earlier in this pass then don't bother to report its removal
+         * right here as a change (since the original AST state is being restored). Also remove
+         * 'explicitNode' from the list of "possibly live" nodes so that it does not get reported as
+         * a change at the end of the pass.
+         */
+        if (!maybeTemporarilyLiveNodes.remove(explicitNode)) {
+          compiler.reportChangeToEnclosingScope(explicitNode);
+        }
+        explicitNode.detach();
+      }
+    }
+
+    private void replaceWith(Node replacement) {
+      replacementNode = replacement;
+      if (firstModule == minimumModule) {
+        firstNode.getParent().addChildBefore(replacementNode, firstNode);
+      } else {
+        // In this case, the name was implicitly provided by two independent
+        // modules. We need to move this code up to a common module.
+        int indexOfDot = namespace.lastIndexOf('.');
+        if (indexOfDot == -1) {
+          // Any old place is fine.
+          compiler.getNodeForCodeInsertion(minimumModule)
+              .addChildToBack(replacementNode);
+        } else {
+          // Add it after the parent namespace.
+          ProvidedName parentName =
+              providedNames.get(namespace.substring(0, indexOfDot));
+          checkNotNull(parentName);
+          checkNotNull(parentName.replacementNode);
+          parentName.replacementNode.getParent().addChildAfter(
+              replacementNode, parentName.replacementNode);
+        }
+      }
+      compiler.reportChangeToEnclosingScope(replacementNode);
+    }
+
+    /**
+     * Create the declaration node for this name, without inserting it
+     * into the AST.
+     */
+    private Node createDeclarationNode(Node value) {
+      if (namespace.indexOf('.') == -1) {
+        return makeVarDeclNode(value);
+      } else {
+        return makeAssignmentExprNode(value);
+      }
+    }
+
+    /**
+     * Creates a simple namespace variable declaration
+     * (e.g. <code>var foo = {};</code>).
+     */
+    private Node makeVarDeclNode(Node value) {
+      Node name = IR.name(namespace);
+      name.addChildToFront(value);
+
+      Node decl = IR.var(name);
+      decl.putBooleanProp(Node.IS_NAMESPACE, true);
+
+      if (compiler.getCodingConvention().isConstant(namespace)) {
+        name.putBooleanProp(Node.IS_CONSTANT_NAME, true);
+      }
+      if (candidateDefinition == null) {
+        decl.setJSDocInfo(NodeUtil.createConstantJsDoc());
+      }
+
+      checkState(isNamespacePlaceholder(decl));
+      setSourceInfo(decl);
+      return decl;
+    }
+
+    /**
+     * Creates a dotted namespace assignment expression
+     * (e.g. <code>foo.bar = {};</code>).
+     */
+    private Node makeAssignmentExprNode(Node value) {
+      Node lhs =
+          NodeUtil.newQName(
+              compiler,
+              namespace,
+              firstNode /* real source info will be filled in below */,
+              namespace);
+      Node decl = IR.exprResult(IR.assign(lhs, value));
+      decl.putBooleanProp(Node.IS_NAMESPACE, true);
+      if (candidateDefinition == null) {
+        decl.getFirstChild().setJSDocInfo(NodeUtil.createConstantJsDoc());
+      }
+      checkState(isNamespacePlaceholder(decl));
+      setSourceInfo(decl);
+      // This function introduces artifical nodes and we don't need them for indexing.
+      // Marking all but the last one as non-indexable. So if this function adds:
+      // foo.bar.baz = {};
+      // then we mark foo and bar as non-indexable.
+      lhs.getFirstChild().makeNonIndexableRecursive();
+      return decl;
+    }
+
+    /**
+     * Copy source info to the new node.
+     */
+    private void setSourceInfo(Node newNode) {
+      Node provideStringNode = getProvideStringNode();
+      int offset = provideStringNode == null ? 0 : getSourceInfoOffset();
+      Node sourceInfoNode = provideStringNode == null ? firstNode : provideStringNode;
+      newNode.useSourceInfoIfMissingFromForTree(sourceInfoNode);
+      if (offset != 0) {
+        newNode.setSourceEncodedPositionForTree(
+            sourceInfoNode.getSourcePosition() + offset);
+      }
+    }
+
+    /**
+     * Get the offset into the provide node where the symbol appears.
+     */
+    private int getSourceInfoOffset() {
+      int indexOfLastDot = namespace.lastIndexOf('.');
+
+      // +1 for the opening quote
+      // +1 for the dot
+      // if there's no dot, then the -1 index cancels it out
+      // so elegant!
+      return 2 + indexOfLastDot;
+    }
+
+    private Node getProvideStringNode() {
+      return (firstNode.getFirstChild() != null && NodeUtil.isExprCall(firstNode))
+          ? firstNode.getFirstChild().getLastChild()
+          : null;
+    }
+  }
+
+  private JSDocInfo createUnknownTypeJsDocInfo() {
+    JSDocInfoBuilder castToUnknownBuilder = new JSDocInfoBuilder(true);
+    castToUnknownBuilder.recordType(
+        new JSTypeExpression(
+            JsDocInfoParser.parseTypeString("?"), "<ProcessClosurePrimitives.java>"));
+    return castToUnknownBuilder.build();
+  }
+
+  /**
+   * @return Whether the node is namespace placeholder.
+   */
+  private static boolean isNamespacePlaceholder(Node n) {
+    if (!n.getBooleanProp(Node.IS_NAMESPACE)) {
+      return false;
+    }
+
+    Node value = null;
+    if (n.isExprResult()) {
+      Node assign = n.getFirstChild();
+      value = assign.getLastChild();
+    } else if (n.isVar()) {
+      Node name = n.getFirstChild();
+      value = name.getFirstChild();
+    }
+
+    if (value == null) {
+      return false;
+    }
+    if (value.isCast()) {
+      // There may be a cast to unknown type wrapped around the value.
+      value = value.getOnlyChild();
+    }
+    return value.isObjectLit() && !value.hasChildren();
+  }
+
+  /**
+   * The string in {@code n} is a reference name. Create a synthetic
+   * node for it with all the proper source info, and add it to the symbol
+   * table.
+   */
+  private void maybeAddStringNodeToSymbolTable(Node n) {
+    if (preprocessorSymbolTable == null) {
+      return;
+    }
+
+    String name = n.getString();
+    Node syntheticRef = NodeUtil.newQName(
+        compiler, name,
+        n /* real source offsets will be filled in below */,
+        name);
+
+    // Offsets to add to source. Named for documentation purposes.
+    final int forQuote = 1;
+    final int forDot = 1;
+
+    Node current = null;
+    for (current = syntheticRef;
+         current.isGetProp();
+         current = current.getFirstChild()) {
+      int fullLen = current.getQualifiedName().length();
+      int namespaceLen = current.getFirstChild().getQualifiedName().length();
+
+      current.setSourceEncodedPosition(n.getSourcePosition() + forQuote);
+      current.setLength(fullLen);
+
+      current.getLastChild().setSourceEncodedPosition(
+          n.getSourcePosition() + namespaceLen + forQuote + forDot);
+      current.getLastChild().setLength(
+          current.getLastChild().getString().length());
+    }
+
+    current.setSourceEncodedPosition(n.getSourcePosition() + forQuote);
+    current.setLength(current.getString().length());
+
+    maybeAddToSymbolTable(syntheticRef);
+  }
+
+  /**
+   * Add the given qualified name node to the symbol table.
+   */
+  private void maybeAddToSymbolTable(Node n) {
+    if (preprocessorSymbolTable != null) {
+      preprocessorSymbolTable.addReference(n);
+    }
+  }
+
+  // -------------------------------------------------------------------------
+
+  /**
+   * Information required to create a {@code MISSING_PROVIDE_ERROR} warning.
+   */
+  private static class UnrecognizedRequire {
+    final Node requireNode;
+    final String namespace;
+    final boolean isRequireType;
+
+    UnrecognizedRequire(Node requireNode, String namespace, boolean isRequireType) {
+      this.requireNode = requireNode;
+      this.namespace = namespace;
+      this.isRequireType = isRequireType;
+    }
+  }
+}
diff --git a/compiler-jx/src/main/java/com/google/javascript/jscomp/RenamePropertiesWithModuleSupport.java b/compiler-jx/src/main/java/com/google/javascript/jscomp/RenamePropertiesWithModuleSupport.java
new file mode 100644
index 0000000..89ba74a
--- /dev/null
+++ b/compiler-jx/src/main/java/com/google/javascript/jscomp/RenamePropertiesWithModuleSupport.java
@@ -0,0 +1,559 @@
+/*
+ * Copyright 2004 The Closure Compiler Authors.
+ *
+ * Licensed 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 com.google.javascript.jscomp;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+import com.google.javascript.jscomp.AbstractCompiler.LifeCycleStage;
+import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback;
+import com.google.javascript.rhino.IR;
+import com.google.javascript.rhino.Node;
+import com.google.javascript.rhino.TokenStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import javax.annotation.Nullable;
+
+/**
+ * Apache Royale copied RenameProperties and modified it to handle
+ * Royale modules.
+ * 
+ * RenameProperties renames properties (including methods) of all JavaScript
+ * objects. This includes prototypes, functions, object literals, etc.
+ *
+ * <p> If provided a VariableMap of previously used names, it tries to reuse
+ * those names.
+ *
+ * <p> To prevent a property from getting renamed you may extern it (add it to
+ * your externs file) or put it in quotes.
+ *
+ * <p> To avoid run-time JavaScript errors, use quotes when accessing properties
+ * that are defined using quotes.
+ *
+ * <pre>
+ *   var a = {'myprop': 0}, b = a['myprop'];  // correct
+ *   var x = {'myprop': 0}, y = x.myprop;     // incorrect
+ * </pre>
+ *
+ * This pass also recognizes and replaces special renaming functions. They supply
+ * a property name as the string literal for the first argument.
+ * This pass will replace them as though they were JS property
+ * references. Here are two examples:
+ *    JSCompiler_renameProperty('propertyName') -> 'jYq'
+ *    JSCompiler_renameProperty('myProp.nestedProp.innerProp') -> 'e4.sW.C$'
+ *
+ */
+class RenamePropertiesWithModuleSupport implements CompilerPass {
+  private static final Splitter DOT_SPLITTER = Splitter.on('.');
+
+  private final AbstractCompiler compiler;
+  private final boolean generatePseudoNames;
+
+  /** Property renaming map from a previous compilation. */
+  private final VariableMap prevUsedPropertyMap;
+  
+  /** Original names of properties that were renamed */
+  private final List<String> prevUsedPropertyOldNames = new ArrayList<String>();
+
+  private final List<Node> toRemove = new ArrayList<Node>();
+  private final List<Node> stringNodesToRename = new ArrayList<Node>();
+  private final Map<Node, Node> callNodeToParentMap =
+      new LinkedHashMap<Node, Node>();
+  private final char[] reservedFirstCharacters;
+  private final char[] reservedNonFirstCharacters;
+
+  // Map from property name to Property object
+  private final Map<String, Property> propertyMap = new LinkedHashMap<String, Property>();
+
+  // Property names that don't get renamed
+  private final Set<String> externedNames = new LinkedHashSet<String>(
+      Arrays.asList("prototype"));
+
+  // Names to which properties shouldn't be renamed, to avoid name conflicts
+  private final Set<String> quotedNames = new LinkedHashSet<String>();
+
+  // Shared name generator
+  private final NameGenerator nameGenerator;
+
+  private static final Comparator<Property> FREQUENCY_COMPARATOR =
+    new Comparator<Property>() {
+      @Override
+      public int compare(Property p1, Property p2) {
+
+        /**
+         * First a frequently used names would always be picked first.
+         */
+        if (p1.numOccurrences != p2.numOccurrences) {
+          return p2.numOccurrences - p1.numOccurrences;
+        }
+
+        /**
+         * Finally, for determinism, we compare them based on the old name.
+         */
+        return p1.oldName.compareTo(p2.oldName);
+       }
+    };
+
+  static final DiagnosticType BAD_CALL = DiagnosticType.error(
+      "JSC_BAD_RENAME_PROPERTY_FUNCTION_NAME_CALL",
+      "Bad {0} call - the first argument must be a string literal");
+
+  static final DiagnosticType BAD_ARG = DiagnosticType.error(
+      "JSC_BAD_RENAME_PROPERTY_FUNCTION_NAME_ARG",
+      "Bad {0} argument - ''{1}'' is not a valid JavaScript identifier");
+
+  /**
+   * Creates an instance.
+   *
+   * @param compiler The JSCompiler
+   * @param generatePseudoNames Generate pseudo names. e.g foo -> $foo$ instead
+   *        of compact obfuscated names. This is used for debugging.
+   * @param nameGenerator a shared NameGenerator that this instance can use;
+   *        the instance may reset or reconfigure it, so the caller should
+   *        not expect any state to be preserved
+   */
+  RenamePropertiesWithModuleSupport(AbstractCompiler compiler, boolean generatePseudoNames,
+      NameGenerator nameGenerator) {
+    this(compiler, generatePseudoNames, null, null, null, nameGenerator);
+  }
+
+  /**
+   * Creates an instance.
+   *
+   * @param compiler The JSCompiler.
+   * @param generatePseudoNames Generate pseudo names. e.g foo -> $foo$ instead
+   *        of compact obfuscated names. This is used for debugging.
+   * @param prevUsedPropertyMap The property renaming map used in a previous
+   *        compilation.
+   * @param nameGenerator a shared NameGenerator that this instance can use;
+   *        the instance may reset or reconfigure it, so the caller should
+   *        not expect any state to be preserved
+   */
+  RenamePropertiesWithModuleSupport(AbstractCompiler compiler,
+      boolean generatePseudoNames, VariableMap prevUsedPropertyMap,
+      NameGenerator nameGenerator) {
+    this(compiler, generatePseudoNames, prevUsedPropertyMap, null, null, nameGenerator);
+  }
+
+  /**
+   * Creates an instance.
+   *
+   * @param compiler The JSCompiler.
+   * @param generatePseudoNames Generate pseudo names. e.g foo -> $foo$ instead of compact
+   *     obfuscated names. This is used for debugging.
+   * @param prevUsedPropertyMap The property renaming map used in a previous compilation.
+   * @param reservedFirstCharacters If specified these characters won't be used in generated names
+   *     for the first character
+   * @param reservedNonFirstCharacters If specified these characters won't be used in generated
+   *     names for characters after the first
+   * @param nameGenerator a shared NameGenerator that this instance can use; the instance may reset
+   *     or reconfigure it, so the caller should not expect any state to be preserved
+   */
+  RenamePropertiesWithModuleSupport(
+      AbstractCompiler compiler,
+      boolean generatePseudoNames,
+      VariableMap prevUsedPropertyMap,
+      @Nullable char[] reservedFirstCharacters,
+      @Nullable char[] reservedNonFirstCharacters,
+      NameGenerator nameGenerator) {
+    this.compiler = compiler;
+    this.generatePseudoNames = generatePseudoNames;
+    this.prevUsedPropertyMap = prevUsedPropertyMap;
+    this.reservedFirstCharacters = reservedFirstCharacters;
+    this.reservedNonFirstCharacters = reservedNonFirstCharacters;
+    this.nameGenerator = nameGenerator;
+    externedNames.addAll(compiler.getExternProperties());
+  }
+
+  @Override
+  public void process(Node externs, Node root) {
+    checkState(compiler.getLifeCycleStage().isNormalized());
+
+    if (prevUsedPropertyMap != null) {
+    	prevUsedPropertyOldNames.addAll(prevUsedPropertyMap.getOriginalNameToNewNameMap().keySet());
+    }
+    
+    NodeTraversal.traverse(compiler, root, new ProcessProperties());
+
+    Set<String> reservedNames =
+        Sets.newHashSetWithExpectedSize(externedNames.size() + quotedNames.size());
+
+    // Assign names, sorted by descending frequency to minimize code size.
+    Set<Property> propsByFreq = new TreeSet<Property>(FREQUENCY_COMPARATOR);
+    propsByFreq.addAll(propertyMap.values());
+
+    // First, try and reuse as many property names from the previous compilation
+    // as possible.
+    if (prevUsedPropertyMap != null) {
+      reusePropertyNames(reservedNames, propsByFreq);
+    }
+
+    /* add externed and quoted names after previously renamed
+     * properties are told to re-use their renames from the main
+     * app.  The original code added these names before
+     * trying to reuse previous renames because those
+     * externs are typically from 3rd-party libraries, but
+     * in modules, externs are from the main loading app
+     * and we want to reuse previous renames as much as possible
+     * because classes in the main loading app will make calls
+     * using the renames instead of the exported name so any
+     * override or implementations of interface methods must
+     * also have the same rename.
+     */
+    reservedNames.addAll(externedNames);
+    reservedNames.addAll(quotedNames);
+    
+    generateNames(propsByFreq, reservedNames);
+
+    // Update the string nodes.
+    for (Node n : stringNodesToRename) {
+      String oldName = n.getString();
+      Property p = propertyMap.get(oldName);
+      if (p != null && p.newName != null) {
+        checkState(oldName.equals(p.oldName));
+        n.setString(p.newName);
+        if (!p.newName.equals(oldName)) {
+          compiler.reportChangeToEnclosingScope(n);
+        }
+      }
+    }
+
+    // Update the call nodes.
+    for (Map.Entry<Node, Node> nodeEntry : callNodeToParentMap.entrySet()) {
+      Node parent = nodeEntry.getValue();
+      Node firstArg = nodeEntry.getKey().getSecondChild();
+      StringBuilder sb = new StringBuilder();
+      for (String oldName : DOT_SPLITTER.split(firstArg.getString())) {
+        Property p = propertyMap.get(oldName);
+        String replacement;
+        if (p != null && p.newName != null) {
+          checkState(oldName.equals(p.oldName));
+          replacement = p.newName;
+        } else {
+          replacement = oldName;
+        }
+        if (sb.length() > 0) {
+          sb.append('.');
+        }
+        sb.append(replacement);
+      }
+      parent.replaceChild(nodeEntry.getKey(), IR.string(sb.toString()));
+      compiler.reportChangeToEnclosingScope(parent);
+    }
+
+    // Complete queued removals.
+    for (Node n : toRemove) {
+      Node parent = n.getParent();
+      compiler.reportChangeToEnclosingScope(n);
+      n.detach();
+      NodeUtil.markFunctionsDeleted(n, compiler);
+      if (!parent.hasChildren() && !parent.isScript()) {
+        parent.detach();
+      }
+    }
+
+    compiler.setLifeCycleStage(LifeCycleStage.NORMALIZED_OBFUSCATED);
+    // This pass may rename getter or setter properties
+    GatherGettersAndSetterProperties.update(compiler, externs, root);
+  }
+
+  /**
+   * Runs through the list of properties and renames as many as possible with
+   * names from the previous compilation. Also, updates reservedNames with the
+   * set of reused names.
+   * @param reservedNames Reserved names to use during renaming.
+   * @param allProps Properties to rename.
+   */
+  private void reusePropertyNames(Set<String> reservedNames,
+                                  Collection<Property> allProps) {
+    for (Property prop : allProps) {
+      // Check if this node can reuse a name from a previous compilation - if
+      // it can set the newName for the property too.
+      String prevName = prevUsedPropertyMap.lookupNewName(prop.oldName);
+      if (!generatePseudoNames && prevName != null) {
+        // We can reuse prevName if it's not reserved.
+        if (reservedNames.contains(prevName)) {
+          continue;
+        }
+
+        prop.newName = prevName;
+        reservedNames.add(prevName);
+      }
+    }
+  }
+
+  /**
+   * Generates new names for properties.
+   *
+   * @param props Properties to generate new names for
+   * @param reservedNames A set of names to which properties should not be
+   *     renamed
+   */
+  private void generateNames(Set<Property> props, Set<String> reservedNames) {
+    nameGenerator.reset(reservedNames, "", reservedFirstCharacters, reservedNonFirstCharacters);
+    for (Property p : props) {
+      if (generatePseudoNames) {
+        p.newName = "$" + p.oldName + "$";
+      } else {
+        // If we haven't already given this property a reusable name.
+        if (p.newName == null) {
+          p.newName = nameGenerator.generateNextName();
+        }
+      }
+      reservedNames.add(p.newName);
+    }
+  }
+
+  /**
+   * Gets the property renaming map (the "answer key").
+   *
+   * @return A mapping from original names to new names
+   */
+  VariableMap getPropertyMap() {
+    ImmutableMap.Builder<String, String> map = ImmutableMap.builder();
+    for (Property p : propertyMap.values()) {
+      if (p.newName != null) {
+        map.put(p.oldName, p.newName);
+      }
+    }
+    return new VariableMap(map.build());
+  }
+
+
+  // -------------------------------------------------------------------------
+
+  /**
+   * A traversal callback that collects property names and counts how
+   * frequently each property name occurs.
+   */
+  private class ProcessProperties extends AbstractPostOrderCallback {
+
+    @Override
+    public void visit(NodeTraversal t, Node n, Node parent) {
+      switch (n.getToken()) {
+        case COMPUTED_PROP:
+          break;
+        case GETPROP:
+          Node propNode = n.getSecondChild();
+          if (propNode.isString()) {
+            if (compiler.getCodingConvention().blockRenamingForProperty(
+                propNode.getString())) {
+              externedNames.add(propNode.getString());
+              break;
+            }
+            maybeMarkCandidate(propNode);
+          }
+          break;
+        case OBJECTLIT:
+          for (Node key = n.getFirstChild(); key != null; key = key.getNext()) {
+            if (key.isComputedProp()) {
+              // We don't want to rename computed properties
+              continue;
+            } else if (key.isQuotedString()) {
+              // Ensure that we never rename some other property in a way
+              // that could conflict with this quoted key.
+              quotedNames.add(key.getString());
+            } else if (compiler.getCodingConvention().blockRenamingForProperty(key.getString())) {
+              externedNames.add(key.getString());
+            } else {
+              maybeMarkCandidate(key);
+            }
+          }
+          break;
+        case OBJECT_PATTERN:
+          // Iterate through all the nodes in the object pattern
+          for (Node key = n.getFirstChild(); key != null; key = key.getNext()) {
+            if (key.isComputedProp()) {
+              // We don't want to rename computed properties
+              continue;
+            } else if (key.isQuotedString()) {
+              // Ensure that we never rename some other property in a way
+              // that could conflict with this quoted key.
+              quotedNames.add(key.getString());
+            } else if (compiler.getCodingConvention().blockRenamingForProperty(key.getString())) {
+              externedNames.add(key.getString());
+            } else {
+              maybeMarkCandidate(key);
+            }
+          }
+          break;
+        case GETELEM:
+          // If this is a quoted property access (e.g. x['myprop']), we need to
+          // ensure that we never rename some other property in a way that
+          // could conflict with this quoted name.
+          Node child = n.getLastChild();
+          if (child != null && child.isString()) {
+            quotedNames.add(child.getString());
+          }
+          break;
+        case CALL: {
+          // We replace property renaming function calls with a string
+          // containing the renamed property.
+          Node fnName = n.getFirstChild();
+          if (compiler
+              .getCodingConvention()
+              .isPropertyRenameFunction(fnName.getOriginalQualifiedName())) {
+            callNodeToParentMap.put(n, parent);
+            countCallCandidates(t, n);
+          }
+          break;
+        }
+        case CLASS_MEMBERS:
+          {
+            // Replace function names defined in a class scope
+            for (Node key = n.getFirstChild(); key != null; key = key.getNext()) {
+              if (key.isComputedProp()) {
+                // We don't want to rename computed properties.
+                continue;
+              } else {
+                Node member = key.getFirstChild();
+
+                String memberDefName = key.getString();
+                if (member.isFunction()) {
+                  Node fnName = member.getFirstChild();
+                  if (compiler.getCodingConvention().blockRenamingForProperty(memberDefName)) {
+                    externedNames.add(fnName.getString());
+                  } else if (memberDefName.equals("constructor")
+                      || memberDefName.equals("superClass_")) {
+                    // TODO (simarora) is there a better way to identify these externs?
+                    externedNames.add(fnName.getString());
+                  } else {
+                    maybeMarkCandidate(key);
+                  }
+                }
+              }
+            }
+            break;
+          }
+        case FUNCTION:
+          {
+            // We eliminate any stub implementations of JSCompiler_renameProperty
+            // that we encounter.
+            if (NodeUtil.isFunctionDeclaration(n)) {
+              String name = n.getFirstChild().getString();
+              if (NodeUtil.JSC_PROPERTY_NAME_FN.equals(name)) {
+                toRemove.add(n);
+              }
+            } else if (parent.isName()
+                && NodeUtil.JSC_PROPERTY_NAME_FN.equals(parent.getString())) {
+              Node varNode = parent.getParent();
+              if (varNode.isVar()) {
+                toRemove.add(parent);
+              }
+            } else if (NodeUtil.isFunctionExpression(n)
+                && parent.isAssign()
+                && parent.getFirstChild().isGetProp()
+                && compiler
+                    .getCodingConvention()
+                    .isPropertyRenameFunction(parent.getFirstChild().getOriginalQualifiedName())) {
+              Node exprResult = parent.getParent();
+              if (exprResult.isExprResult()
+                  && NodeUtil.isStatementBlock(exprResult.getParent())
+                  && exprResult.getFirstChild().isAssign()) {
+                toRemove.add(exprResult);
+              }
+            }
+            break;
+          }
+        default:
+          break;
+      }
+    }
+
+    /**
+     * If a property node is eligible for renaming, stashes a reference to it
+     * and increments the property name's access count.
+     *
+     * @param n The STRING node for a property
+     */
+    private void maybeMarkCandidate(Node n) {
+      String name = n.getString();
+      if (!externedNames.contains(name) || prevUsedPropertyOldNames.contains(name)) {
+        stringNodesToRename.add(n);
+        countPropertyOccurrence(name);
+      }
+    }
+
+    /**
+     * Counts references to property names that occur in a special function
+     * call.
+     *
+     * @param callNode The CALL node for a property
+     * @param t The traversal
+     */
+    private void countCallCandidates(NodeTraversal t, Node callNode) {
+      String fnName = callNode.getFirstChild().getOriginalName();
+      if (fnName == null) {
+        fnName = callNode.getFirstChild().getString();
+      }
+      Node firstArg = callNode.getSecondChild();
+      if (!firstArg.isString()) {
+        t.report(callNode, BAD_CALL, fnName);
+        return;
+      }
+
+      for (String name : DOT_SPLITTER.split(firstArg.getString())) {
+        if (!TokenStream.isJSIdentifier(name)) {
+          t.report(callNode, BAD_ARG, fnName);
+          continue;
+        }
+        if (!externedNames.contains(name) || prevUsedPropertyOldNames.contains(name)) {
+          countPropertyOccurrence(name);
+        }
+      }
+    }
+
+    /**
+     * Increments the occurrence count for a property name.
+     *
+     * @param name The property name
+     */
+    private void countPropertyOccurrence(String name) {
+      Property prop = propertyMap.get(name);
+      if (prop == null) {
+        prop = new Property(name);
+        propertyMap.put(name, prop);
+      }
+      prop.numOccurrences++;
+    }
+  }
+
+  // -------------------------------------------------------------------------
+
+  /**
+   * Encapsulates the information needed for renaming a property.
+   */
+  private static class Property {
+    final String oldName;
+    String newName;
+    int numOccurrences;
+
+    Property(String name) {
+      this.oldName = name;
+    }
+  }
+}
diff --git a/compiler-jx/src/main/java/com/google/javascript/jscomp/RenameVarsWithModuleSupport.java b/compiler-jx/src/main/java/com/google/javascript/jscomp/RenameVarsWithModuleSupport.java
new file mode 100644
index 0000000..c7b104b
--- /dev/null
+++ b/compiler-jx/src/main/java/com/google/javascript/jscomp/RenameVarsWithModuleSupport.java
@@ -0,0 +1,647 @@
+/*
+ * Copyright 2004 The Closure Compiler Authors.
+ *
+ * Licensed 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 com.google.javascript.jscomp;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.base.Strings.nullToEmpty;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ListMultimap;
+import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback;
+import com.google.javascript.jscomp.NodeTraversal.ScopedCallback;
+import com.google.javascript.rhino.Node;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import javax.annotation.Nullable;
+
+/**
+ * Apache Royale copied RenameVars and modified it to handle
+ * Royale modules.
+ * 
+ * RenameVars renames all the variables names into short names, to reduce code
+ * size and also to obfuscate the code.
+ *
+ */
+final class RenameVarsWithModuleSupport implements CompilerPass {
+
+  /**
+   * Limit on number of locals in a scope for temporary local renaming
+   * when {@code preferStableNames} is true.
+   */
+  private static final int MAX_LOCALS_IN_SCOPE_TO_TEMP_RENAME = 1000;
+
+  private final AbstractCompiler compiler;
+
+  /** List of global NAME nodes */
+  private final ArrayList<Node> globalNameNodes = new ArrayList<Node>();
+
+  /** List of local NAME nodes */
+  private final ArrayList<Node> localNameNodes = new ArrayList<Node>();
+
+  /** Mapping of original names for change detection */
+  private final Map<Node, String> originalNameByNode = new HashMap<Node, String>();
+
+  /**
+   * Maps a name node to its pseudo name, null if we are not generating so
+   * there will be no overhead unless we are debugging.
+   */
+  private final Map<Node, String> pseudoNameMap;
+
+  /** Set of extern variable names */
+  private Set<String> externNames;
+
+  /** Set of reserved variable names */
+  private final Set<String> reservedNames;
+
+  /** The renaming map */
+  private final Map<String, String> renameMap = new HashMap<String, String>();
+
+  /** The previously used rename map. */
+  private final VariableMap prevUsedRenameMap;
+
+  /** The global name prefix */
+  private final String prefix;
+
+  /** Counter for each assignment */
+  private int assignmentCount = 0;
+
+  // Logic for bleeding functions, where the name leaks into the outer
+  // scope on IE but not on other browsers.
+  private final Set<Var> localBleedingFunctions = new HashSet<Var>();
+  private final ListMultimap<Scope, Var> localBleedingFunctionsPerScope =
+      ArrayListMultimap.create();
+
+  class Assignment {
+    final boolean isLocal;
+    final String oldName;
+    final int orderOfOccurrence;
+    String newName;
+    int count; // Number of times this is referenced
+
+    Assignment(String name) {
+      this.isLocal = name.startsWith(LOCAL_VAR_PREFIX);
+      this.oldName = name;
+      this.newName = null;
+      this.count = 0;
+
+      // Represents the order at which a symbol appears in the source.
+      this.orderOfOccurrence = assignmentCount++;
+    }
+
+    /**
+     * Assigns the new name.
+     */
+    void setNewName(String newName) {
+      checkState(this.newName == null);
+      this.newName = newName;
+    }
+  }
+
+  /** Maps an old name to a new name assignment */
+  private final Map<String, Assignment> assignments =
+      new HashMap<String, Assignment>();
+
+  /** Whether renaming should apply to local variables only. */
+  private final boolean localRenamingOnly;
+
+  /**
+   * Whether function expression names should be preserved. Typically, for
+   * debugging purposes.
+   *
+   * @see NameAnonymousFunctions
+   */
+  private final boolean preserveFunctionExpressionNames;
+
+  private final boolean shouldShadow;
+
+  private final boolean preferStableNames;
+
+  /** Characters that shouldn't be used in variable names. */
+  private final char[] reservedCharacters;
+
+  /** A prefix to distinguish temporary local names from global names */
+  private static final String LOCAL_VAR_PREFIX = "L ";
+
+  // Shared name generator
+  private final NameGenerator nameGenerator;
+
+  /* list of aliases from the externs */
+  private List<String> externAliases;
+  
+  /*
+   * nameGenerator is a shared NameGenerator that this instance can use;
+   * the instance may reset or reconfigure it, so the caller should
+   * not expect any state to be preserved.
+   */
+  RenameVarsWithModuleSupport(AbstractCompiler compiler, String prefix,
+      boolean localRenamingOnly, boolean preserveFunctionExpressionNames,
+      boolean generatePseudoNames, boolean shouldShadow,
+      boolean preferStableNames, VariableMap prevUsedRenameMap,
+      @Nullable char[] reservedCharacters,
+      @Nullable Set<String> reservedNames,
+      NameGenerator nameGenerator) {
+    this.compiler = compiler;
+    this.prefix = nullToEmpty(prefix);
+    this.localRenamingOnly = localRenamingOnly;
+    this.preserveFunctionExpressionNames = preserveFunctionExpressionNames;
+    if (generatePseudoNames) {
+      this.pseudoNameMap = new HashMap<Node, String>();
+    } else {
+      this.pseudoNameMap = null;
+    }
+    this.prevUsedRenameMap = prevUsedRenameMap;
+    this.reservedCharacters = reservedCharacters;
+    this.shouldShadow = shouldShadow;
+    this.preferStableNames = preferStableNames;
+    if (reservedNames == null) {
+      this.reservedNames = new HashSet<String>();
+    } else {
+      this.reservedNames = new HashSet<String>(reservedNames);
+    }
+    this.nameGenerator = nameGenerator;
+  }
+
+  /**
+   * Iterate through the nodes, collect all the NAME nodes that need to be
+   * renamed, and count how many times each variable name is referenced.
+   *
+   * Keep track of all name references in globalNameNodes, and localNameNodes.
+   *
+   * To get shorter local variable renaming, we rename local variables to a
+   * temporary name "LOCAL_VAR_PREFIX + index" where index is the index of the
+   * variable declared in the local scope stack.
+   * e.g.
+   * Foo(fa, fb) {
+   *   var c = function(d, e) { return fa; }
+   * }
+   * The indexes are: fa:0, fb:1, c:2, d:3, e:4
+   *
+   * In that way, local variable names are reused in each global function.
+   * e.g. the final code might look like
+   * function x(a,b) { ... }
+   * function y(a,b,c) { ... }
+   */
+  class ProcessVars extends AbstractPostOrderCallback implements ScopedCallback {
+
+    @Override
+    public void enterScope(NodeTraversal t) {
+      if (t.inGlobalHoistScope() || !shouldTemporarilyRenameLocalsInScope(t.getScope())) {
+        return;
+      }
+      Scope scope = t.getScope();
+      for (Var current : scope.getVarIterable()) {
+        if (current.isBleedingFunction()) {
+          localBleedingFunctions.add(current);
+          localBleedingFunctionsPerScope.put(
+              scope.getParent(), current);
+        }
+      }
+    }
+
+    @Override
+    public void exitScope(NodeTraversal t) {}
+
+    @Override
+    public void visit(NodeTraversal t, Node n, Node parent) {
+      if (!(n.isName() || n.isImportStar())) {
+        return;
+      }
+
+      String name = n.getString();
+
+      // Ignore anonymous functions and classes.
+      if (name.isEmpty()) {
+        return;
+      }
+
+      // "import {x as y} from 'm';"
+      // Skip x because it's not a variable in this scope.
+      if (parent.isImportSpec() && parent.hasTwoChildren() && parent.getFirstChild() == n) {
+        return;
+      }
+
+      // Is this local or Global?
+      // Bleeding functions should be treated as part of their outer
+      // scope, because IE has bugs in how it handles bleeding
+      // functions.
+      Var var = t.getScope().getVar(name);
+      boolean local =
+          var != null
+              && var.isLocal()
+              && (var.scope.getParent().isLocal() || !var.isBleedingFunction());
+
+      // Never rename references to the arguments array
+      if (var != null && var.isArguments()) {
+        reservedNames.add(name);
+        return;
+      }
+
+      // Are we renaming global variables?
+      if (!local && localRenamingOnly) {
+        reservedNames.add(name);
+        return;
+      }
+
+      // Are we renaming function expression names?
+      if (preserveFunctionExpressionNames && var != null
+          && NodeUtil.isFunctionExpression(var.getParentNode())) {
+        reservedNames.add(name);
+        return;
+      }
+
+      // Check if we can rename this.
+      if (!okToRenameVar(name, local)) {
+        if (local) {
+          // Blindly de-uniquify for the Prototype library for
+          // http://blickly.github.io/closure-compiler-issues/#103
+          String newName = MakeDeclaredNamesUnique.ContextualRenameInverter.getOriginalName(name);
+          if (!newName.equals(name)) {
+            n.setString(newName);
+          }
+        }
+        return;
+      }
+
+      if (pseudoNameMap != null) {
+        recordPseudoName(n);
+      }
+
+      if (local && shouldTemporarilyRenameLocalsInScope(var.getScope())) {
+        // Give local variables a temporary name based on the
+        // variable's index in the scope to enable name reuse across
+        // locals in independent scopes.
+        String tempName = LOCAL_VAR_PREFIX + getLocalVarIndex(var);
+        incCount(tempName);
+        localNameNodes.add(n);
+        // Remember the original string in a name before it's temporarily filled with an "L".
+        originalNameByNode.put(n, n.getString());
+        n.setString(tempName);
+      } else if (var != null) { // Not an extern
+        // If it's global, increment global count
+        incCount(name);
+        globalNameNodes.add(n);
+      }
+    }
+
+    // Increment count of an assignment
+    void incCount(String name) {
+      Assignment s = assignments.get(name);
+      if (s == null) {
+        s = new Assignment(name);
+        assignments.put(name, s);
+      }
+      s.count++;
+    }
+  }
+
+  /**
+   * Sorts Assignment objects by their count, breaking ties by their order of
+   * occurrence in the source to ensure a deterministic total ordering.
+   */
+  private static final Comparator<Assignment> FREQUENCY_COMPARATOR =
+      new Comparator<Assignment>() {
+    @Override
+    public int compare(Assignment a1, Assignment a2) {
+      if (a1.count != a2.count) {
+        return a2.count - a1.count;
+      }
+      // Break a tie using the order in which the variable first appears in
+      // the source.
+      return ORDER_OF_OCCURRENCE_COMPARATOR.compare(a1, a2);
+    }
+  };
+
+  /**
+   * Sorts Assignment objects by the order the variable name first appears in
+   * the source.
+   */
+  private static final Comparator<Assignment> ORDER_OF_OCCURRENCE_COMPARATOR =
+      new Comparator<Assignment>() {
+        @Override
+        public int compare(Assignment a1, Assignment a2) {
+          return a1.orderOfOccurrence - a2.orderOfOccurrence;
+        }
+      };
+
+  @Override
+  public void process(Node externs, Node root) {
+	externAliases = ProcessClosurePrimitivesWithModuleSupport.externedAliases.get(externs);
+    this.externNames = NodeUtil.collectExternVariableNames(this.compiler, externs);
+
+    originalNameByNode.clear();
+
+    // Do variable reference counting.
+    NodeTraversal.traverse(compiler, root, new ProcessVars());
+
+    // Make sure that new names don't overlap with extern names.
+    reservedNames.addAll(externNames);
+
+    // Rename vars, sorted by frequency of occurrence to minimize code size.
+    SortedSet<Assignment> varsByFrequency = new TreeSet<Assignment>(FREQUENCY_COMPARATOR);
+    varsByFrequency.addAll(assignments.values());
+
+    if (shouldShadow) {
+      new ShadowVariablesWithModuleSupport(
+          compiler, assignments, varsByFrequency, pseudoNameMap).process(
+              externs, root);
+    }
+
+    // First try to reuse names from an earlier compilation.
+    if (prevUsedRenameMap != null) {
+      reusePreviouslyUsedVariableMap(varsByFrequency);
+    }
+
+    // now that previous names have been assigned, 
+    // add those previous renames to reserved names
+    // so those variable names don't get re-used in assignNames.
+    if (prevUsedRenameMap != null) {
+    	reservedNames.addAll(prevUsedRenameMap.getNewNameToOriginalNameMap().keySet());
+    }
+    
+    // Assign names, sorted by descending frequency to minimize code size.
+    assignNames(varsByFrequency);
+
+    // Rename the globals!
+    for (Node n : globalNameNodes) {
+      /* A module may have a reference to a class
+       * but no variable defining it since the class
+       * is defined in the main loading app.  Closure 
+       * expects every reference to have a var so in
+       * CollapseProperties, some vars are added so that
+       * they can be collapsed.  However, we don't want those
+       * added vars in the output so here we move them
+       * to externs (if we added them to the externs in 
+       * CollapseProperties they wouldn't get renamed).
+       */ 
+      boolean moveToExternsAfterRename = false;
+      String renamedVar = n.getString();
+      if (prevUsedRenameMap != null && 
+    		  externAliases.contains(renamedVar) &&
+      		  n.getParent().isVar())
+        moveToExternsAfterRename = true;
+      setNameAndReport(n, getNewGlobalName(n));
+      if (moveToExternsAfterRename) {
+        Node p = n.getParent();
+        p.detach();
+        Node externsInput = compiler.getSynthesizedExternsInput().getAstRoot(compiler);
+        externsInput.addChildToBack(p);
+        compiler.reportChangeToEnclosingScope(p);
+      }
+    }
+
+    // Rename the locals!
+    for (Node n : localNameNodes) {
+      setNameAndReport(n, getNewLocalName(n));
+    }
+  }
+
+  private void setNameAndReport(Node n, @Nullable String newName) {
+    // A null newName, indicates it should not be renamed.
+    if (newName != null && !newName.equals(n.getString())) {
+      n.setString(newName);
+
+      // Only mark changes if the final name change is different than it was original before being
+      // filled with the "L" temporary name.
+      if (!newName.equals(originalNameByNode.get(n))) {
+        compiler.reportChangeToEnclosingScope(n);
+        Node parent = n.getParent();
+        if (parent.isFunction() && NodeUtil.isFunctionDeclaration(parent)) {
+          // If we are renaming a function declaration, make sure the containing scope
+          // has the opportunity to act on the change.
+          compiler.reportChangeToEnclosingScope(parent);
+        }
+      }
+    }
+  }
+
+  @Nullable
+  private String getNewGlobalName(Node n) {
+    String oldName = n.getString();
+    Assignment a = assignments.get(oldName);
+    if (a.newName != null && !a.newName.equals(oldName)) {
+      if (pseudoNameMap != null) {
+        return pseudoNameMap.get(n);
+      }
+      return a.newName;
+    } else {
+      return null;
+    }
+  }
+
+  @Nullable
+  private String getNewLocalName(Node n) {
+    String oldTempName = n.getString();
+    Assignment a = assignments.get(oldTempName);
+    if (!a.newName.equals(oldTempName)) {
+      if (pseudoNameMap != null) {
+        return pseudoNameMap.get(n);
+      }
+      return a.newName;
+    }
+    return null;
+  }
+
+  private void recordPseudoName(Node n) {
+    // Variable names should be in a different name space than
+    // property pseudo names.
+    pseudoNameMap.put(n, '$' + n.getString() + "$$");
+  }
+
+  /**
+   * Runs through the assignments and reuses as many names as possible from the previously used
+   * variable map. Updates reservedNames with the set of names that were reused.
+   */
+  private void reusePreviouslyUsedVariableMap(SortedSet<Assignment> varsToRename) {
+    // If prevUsedRenameMap had duplicate values then this pass would be
+    // non-deterministic.
+    // In such a case, the following will throw an IllegalArgumentException.
+    checkNotNull(prevUsedRenameMap.getNewNameToOriginalNameMap());
+    for (Assignment a : varsToRename) {
+      String prevNewName = prevUsedRenameMap.lookupNewName(a.oldName);
+      if (prevNewName == null || reservedNames.contains(prevNewName)) {
+        continue;
+      }
+
+      if (a.isLocal
+          || (!externNames.contains(a.oldName)
+              && prevNewName.startsWith(prefix))) {
+        reservedNames.add(prevNewName);
+        finalizeNameAssignment(a, prevNewName);
+      }
+    }
+  }
+
+  /**
+   * Determines which new names to substitute for the original names.
+   */
+  private void assignNames(SortedSet<Assignment> varsToRename) {
+    NameGenerator globalNameGenerator = null;
+    NameGenerator localNameGenerator = null;
+
+    globalNameGenerator = nameGenerator;
+    nameGenerator.reset(reservedNames, prefix, reservedCharacters);
+
+    // Local variables never need a prefix.
+    // Also, we need to avoid conflicts between global and local variable
+    // names; we do this by having using the same generator (not two
+    // instances). The case where global variables have a prefix (and
+    // therefore we use two different generators) but a local variable name
+    // might nevertheless conflict with a global one is not handled.
+    localNameGenerator =
+        prefix.isEmpty()
+        ? globalNameGenerator
+        : nameGenerator.clone(reservedNames, "", reservedCharacters);
+
+    // Generated names and the assignments for non-local vars.
+    List<Assignment> pendingAssignments = new ArrayList<Assignment>();
+    List<String> generatedNamesForAssignments = new ArrayList<String>();
+
+    for (Assignment a : varsToRename) {
+      if (a.newName != null) {
+        continue;
+      }
+
+      if (externNames.contains(a.oldName)) {
+        continue;
+      }
+
+      String newName;
+      if (a.isLocal) {
+        // For local variable, we make the assignment right away.
+        newName = localNameGenerator.generateNextName();
+        finalizeNameAssignment(a, newName);
+      } else {
+        // For non-local variable, delay finalizing the name assignment
+        // until we know how many new names we'll have of length 2, 3, etc.
+        newName = globalNameGenerator.generateNextName();
+        pendingAssignments.add(a);
+        generatedNamesForAssignments.add(newName);
+      }
+      reservedNames.add(newName);
+    }
+
+    // Now that we have a list of generated names, and a list of variable
+    // Assignment objects, we assign the generated names to the vars as
+    // follows:
+    // 1) The most frequent vars get the shorter names.
+    // 2) If N number of vars are going to be assigned names of the same
+    //    length, we assign the N names based on the order at which the vars
+    //    first appear in the source. This makes the output somewhat less
+    //    random, because symbols declared close together are assigned names
+    //    that are quite similar. With this heuristic, the output is more
+    //    compressible.
+    //    For instance, the output may look like:
+    //    var da = "..", ea = "..";
+    //    function fa() { .. } function ga() { .. }
+
+    int numPendingAssignments = generatedNamesForAssignments.size();
+    for (int i = 0; i < numPendingAssignments;) {
+      SortedSet<Assignment> varsByOrderOfOccurrence =
+          new TreeSet<Assignment>(ORDER_OF_OCCURRENCE_COMPARATOR);
+
+      // Add k number of Assignment to the set, where k is the number of
+      // generated names of the same length.
+      int len = generatedNamesForAssignments.get(i).length();
+      for (int j = i; j < numPendingAssignments
+          && generatedNamesForAssignments.get(j).length() == len; j++) {
+        varsByOrderOfOccurrence.add(pendingAssignments.get(j));
+      }
+
+      // Now, make the assignments
+      for (Assignment a : varsByOrderOfOccurrence) {
+        finalizeNameAssignment(a, generatedNamesForAssignments.get(i));
+        ++i;
+      }
+    }
+  }
+
+  /**
+   * Makes a final name assignment.
+   */
+  private void finalizeNameAssignment(Assignment a, String newName) {
+    a.setNewName(newName);
+
+    // Keep track of the mapping
+    renameMap.put(a.oldName, newName);
+  }
+
+  /**
+   * Gets the variable map.
+   */
+  VariableMap getVariableMap() {
+    return new VariableMap(ImmutableMap.copyOf(renameMap));
+  }
+
+  /**
+   * Determines whether a variable name is okay to rename.
+   */
+  private boolean okToRenameVar(String name, boolean isLocal) {
+    return !compiler.getCodingConvention().isExported(name, isLocal);
+  }
+
+  /**
+   * Returns the index within the scope stack.
+   * e.g. function Foo(a) { var b; function c(d) { } }
+   * a = 0, b = 1, c = 2, d = 3
+   */
+  private int getLocalVarIndex(Var v) {
+    int num = v.index;
+    Scope s = v.scope.getParent();
+    if (s == null) {
+      throw new IllegalArgumentException("Var is not local");
+    }
+
+    boolean isBleedingIntoScope = s.getParent() != null && localBleedingFunctions.contains(v);
+
+    while (s.getParent() != null) {
+      if (isBleedingIntoScope) {
+        num += localBleedingFunctionsPerScope.get(s).indexOf(v) + 1;
+        isBleedingIntoScope = false;
+      } else {
+        num += localBleedingFunctionsPerScope.get(s).size();
+      }
+      if (shouldTemporarilyRenameLocalsInScope(s)) {
+        num += s.getVarCount();
+      }
+      s = s.getParent();
+    }
+    return num;
+  }
+
+  /**
+   * Returns true if the local variables in a scope should be given
+   * temporary names (eg, 'L 123') prior to renaming to allow reuse of
+   * names across scopes.  With {@code preferStableNames}, temporary
+   * renaming is disabled if the number of locals in the scope is
+   * above a heuristic threshold to allow effective reuse of rename
+   * maps (see {@code prevUsedRenameMap}).  In scopes with many
+   * variables the temporary name given to a variable is unlikely to
+   * be the same temporary name used when the rename map was created.
+   */
+  private boolean shouldTemporarilyRenameLocalsInScope(Scope s) {
+    return (!preferStableNames || s.getVarCount() <= MAX_LOCALS_IN_SCOPE_TO_TEMP_RENAME);
+  }
+}
diff --git a/compiler-jx/src/main/java/com/google/javascript/jscomp/RoyaleClosurePassConfig.java b/compiler-jx/src/main/java/com/google/javascript/jscomp/RoyaleClosurePassConfig.java
new file mode 100644
index 0000000..84fae02
--- /dev/null
+++ b/compiler-jx/src/main/java/com/google/javascript/jscomp/RoyaleClosurePassConfig.java
@@ -0,0 +1,3496 @@
+/*
+ * Copyright 2009 The Closure Compiler Authors.
+ *
+ * Licensed 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 com.google.javascript.jscomp;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.javascript.jscomp.PassFactory.createEmptyPass;
+import static com.google.javascript.jscomp.parsing.parser.FeatureSet.ES2018;
+import static com.google.javascript.jscomp.parsing.parser.FeatureSet.ES5;
+import static com.google.javascript.jscomp.parsing.parser.FeatureSet.ES6;
+import static com.google.javascript.jscomp.parsing.parser.FeatureSet.ES8;
+import static com.google.javascript.jscomp.parsing.parser.FeatureSet.ES8_MODULES;
+import static com.google.javascript.jscomp.parsing.parser.FeatureSet.ES_NEXT;
+import static com.google.javascript.jscomp.parsing.parser.FeatureSet.TYPESCRIPT;
+import static com.google.javascript.jscomp.parsing.parser.FeatureSet.TYPE_CHECK_SUPPORTED;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.javascript.jscomp.AbstractCompiler.LifeCycleStage;
+import com.google.javascript.jscomp.CompilerOptions.ExtractPrototypeMemberDeclarationsMode;
+import com.google.javascript.jscomp.CompilerOptions.Reach;
+import com.google.javascript.jscomp.CoverageInstrumentationPass.CoverageReach;
+import com.google.javascript.jscomp.CoverageInstrumentationPass.InstrumentOption;
+import com.google.javascript.jscomp.ExtractPrototypeMemberDeclarations.Pattern;
+import com.google.javascript.jscomp.NodeTraversal.Callback;
+import com.google.javascript.jscomp.PassFactory.HotSwapPassFactory;
+import com.google.javascript.jscomp.ijs.ConvertToTypedInterface;
+import com.google.javascript.jscomp.lint.CheckArrayWithGoogObject;
+import com.google.javascript.jscomp.lint.CheckDuplicateCase;
+import com.google.javascript.jscomp.lint.CheckEmptyStatements;
+import com.google.javascript.jscomp.lint.CheckEnums;
+import com.google.javascript.jscomp.lint.CheckEs6ModuleFileStructure;
+import com.google.javascript.jscomp.lint.CheckEs6Modules;
+import com.google.javascript.jscomp.lint.CheckInterfaces;
+import com.google.javascript.jscomp.lint.CheckJSDocStyle;
+import com.google.javascript.jscomp.lint.CheckMissingSemicolon;
+import com.google.javascript.jscomp.lint.CheckNoMutatedEs6Exports;
+import com.google.javascript.jscomp.lint.CheckNullabilityModifiers;
+import com.google.javascript.jscomp.lint.CheckNullableReturn;
+import com.google.javascript.jscomp.lint.CheckPrimitiveAsObject;
+import com.google.javascript.jscomp.lint.CheckPrototypeProperties;
+import com.google.javascript.jscomp.lint.CheckRequiresAndProvidesSorted;
+import com.google.javascript.jscomp.lint.CheckUnusedLabels;
+import com.google.javascript.jscomp.lint.CheckUselessBlocks;
+import com.google.javascript.jscomp.parsing.ParserRunner;
+import com.google.javascript.jscomp.parsing.parser.FeatureSet;
+import com.google.javascript.rhino.IR;
+import com.google.javascript.rhino.Node;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nullable;
+
+/**
+ * Pass factories and meta-data for native JSCompiler passes.
+ *
+ * @author nicksantos@google.com (Nick Santos)
+ *
+ * Apache Royale copied DefaultPassConfig and modified it to replace
+ * two passes with "WithModuleSupport" passes.
+ * 
+ * NOTE(dimvar): this needs some non-trivial refactoring. The pass config should
+ * use as little state as possible. The recommended way for a pass to leave
+ * behind some state for a subsequent pass is through the compiler object.
+ * Any other state remaining here should only be used when the pass config is
+ * creating the list of checks and optimizations, not after passes have started
+ * executing. For example, the field namespaceForChecks should be in Compiler.
+ */
+public final class RoyaleClosurePassConfig extends PassConfig {
+
+  /* For the --mark-as-compiled pass */
+  private static final String COMPILED_CONSTANT_NAME = "COMPILED";
+
+  /* Constant name for Closure's locale */
+  private static final String CLOSURE_LOCALE_CONSTANT_NAME = "goog.LOCALE";
+
+  static final DiagnosticType CANNOT_USE_PROTOTYPE_AND_VAR =
+      DiagnosticType.error("JSC_CANNOT_USE_PROTOTYPE_AND_VAR",
+          "Rename prototypes and inline variables cannot be used together.");
+
+  // Miscellaneous errors.
+  private static final java.util.regex.Pattern GLOBAL_SYMBOL_NAMESPACE_PATTERN =
+    java.util.regex.Pattern.compile("^[a-zA-Z0-9$_]+$");
+
+  /**
+   * A global namespace to share across checking passes.
+   */
+  private transient GlobalNamespace namespaceForChecks = null;
+
+  /** A symbol table for registering references that get removed during preprocessing. */
+  private final transient PreprocessorSymbolTable.CachedInstanceFactory
+      preprocessorSymbolTableFactory;
+
+  /**
+   * Global state necessary for doing hotswap recompilation of files with references to
+   * processed goog.modules.
+   */
+  private transient ClosureRewriteModule.GlobalRewriteState moduleRewriteState = null;
+
+  /**
+   * Whether to protect "hidden" side-effects.
+   * @see CheckSideEffects
+   */
+  private final boolean protectHiddenSideEffects;
+  
+  /** name of a source file we can use to inject other code */
+  private String sourceFileName;
+
+  /** file of already renamed vars */
+  private File varRenameMapFile;
+  
+  public RoyaleClosurePassConfig(CompilerOptions options, String sourceFileName, File varRenameMapFile) {
+    super(options);
+
+    // The current approach to protecting "hidden" side-effects is to
+    // wrap them in a function call that is stripped later, this shouldn't
+    // be done in IDE mode where AST changes may be unexpected.
+    protectHiddenSideEffects = options != null && options.shouldProtectHiddenSideEffects();
+    preprocessorSymbolTableFactory = new PreprocessorSymbolTable.CachedInstanceFactory();
+    this.varRenameMapFile = varRenameMapFile;
+    this.sourceFileName = sourceFileName;
+  }
+
+  GlobalNamespace getGlobalNamespace() {
+    return namespaceForChecks;
+  }
+
+  @Nullable
+  PreprocessorSymbolTable getPreprocessorSymbolTable() {
+    return preprocessorSymbolTableFactory.getInstanceOrNull();
+  }
+
+  void maybeInitializeModuleRewriteState() {
+    if (options.allowsHotswapReplaceScript() && this.moduleRewriteState == null) {
+      this.moduleRewriteState = new ClosureRewriteModule.GlobalRewriteState();
+    }
+  }
+
+  @Override
+  protected List<PassFactory> getTranspileOnlyPasses() {
+    List<PassFactory> passes = new ArrayList<PassFactory>();
+
+    if (options.needsTranspilationFrom(TYPESCRIPT)) {
+      passes.add(convertEs6TypedToEs6);
+    }
+
+    passes.add(checkVariableReferencesForTranspileOnly);
+    passes.add(gatherModuleMetadataPass);
+
+    if (options.getLanguageIn().toFeatureSet().has(FeatureSet.Feature.MODULES)) {
+      passes.add(rewriteGoogJsImports);
+      switch (options.getEs6ModuleTranspilation()) {
+        case COMPILE:
+          TranspilationPasses.addEs6ModulePass(passes, preprocessorSymbolTableFactory);
+          break;
+        case TO_COMMON_JS_LIKE_MODULES:
+          TranspilationPasses.addEs6ModuleToCjsPass(passes);
+          break;
+        case RELATIVIZE_IMPORT_PATHS:
+          TranspilationPasses.addEs6RewriteImportPathPass(passes);
+          break;
+        case NONE:
+          // nothing
+          break;
+      }
+    }
+
+    passes.add(checkSuper);
+
+    // It's important that the Dart super accessors pass run *before* es6ConvertSuper,
+    // which is a "late" ES6 pass. This is enforced in the assertValidOrder method.
+    if (options.dartPass && options.needsTranspilationFrom(ES6)) {
+      passes.add(dartSuperAccessorsPass);
+    }
+
+    TranspilationPasses.addPreTypecheckTranspilationPasses(passes, options);
+
+    TranspilationPasses.addPostCheckTranspilationPasses(passes, options);
+
+    if (options.needsTranspilationFrom(ES6)) {
+      if (options.rewritePolyfills) {
+        TranspilationPasses.addRewritePolyfillPass(passes);
+      }
+    }
+
+    passes.add(injectRuntimeLibraries);
+
+    assertAllOneTimePasses(passes);
+    assertValidOrderForChecks(passes);
+    return passes;
+  }
+
+  @Override
+  protected List<PassFactory> getWhitespaceOnlyPasses() {
+    List<PassFactory> passes = new ArrayList<PassFactory>();
+
+    if (options.processCommonJSModules) {
+      passes.add(rewriteCommonJsModules);
+    } else if (options.getLanguageIn().toFeatureSet().has(FeatureSet.Feature.MODULES)) {
+      passes.add(rewriteScriptsToEs6Modules);
+    }
+
+    if (options.wrapGoogModulesForWhitespaceOnly) {
+      passes.add(whitespaceWrapGoogModules);
+    }
+    return passes;
+  }
+
+  private void addTypeCheckerPasses(List<PassFactory> checks, CompilerOptions options) {
+    if (!options.allowsHotswapReplaceScript()) {
+      checks.add(inlineTypeAliases);
+    }
+    if (options.checkTypes || options.inferTypes) {
+      checks.add(resolveTypes);
+      checks.add(inferTypes);
+      if (options.checkTypes) {
+        checks.add(checkTypes);
+      } else {
+        checks.add(inferJsDocInfo);
+      }
+
+      // We assume that only clients who are going to re-compile, or do in-depth static analysis,
+      // will need the typed scope creator after the compile job.
+      if (!options.preservesDetailedSourceInfo() && !options.allowsHotswapReplaceScript()) {
+        checks.add(clearTypedScopePass);
+      }
+    }
+  }
+
+  @Override
+  protected List<PassFactory> getChecks() {
+    List<PassFactory> checks = new ArrayList<PassFactory>();
+
+    checks.add(gatherGettersAndSetters);
+
+    if (options.shouldGenerateTypedExterns()) {
+      checks.add(closureGoogScopeAliases);
+      checks.add(closureRewriteClass);
+      checks.add(generateIjs);
+      checks.add(whitespaceWrapGoogModules);
+      return checks;
+    }
+
+    checks.add(createEmptyPass("beforeStandardChecks"));
+
+    if (options.processCommonJSModules) {
+      checks.add(rewriteCommonJsModules);
+    } else if (options.getLanguageIn().toFeatureSet().has(FeatureSet.Feature.MODULES)) {
+      checks.add(rewriteScriptsToEs6Modules);
+    }
+
+    // Note: ChromePass can rewrite invalid @type annotations into valid ones, so should run before
+    // JsDoc checks.
+    if (options.isChromePassEnabled()) {
+      checks.add(chromePass);
+    }
+
+    // Verify JsDoc annotations and check ES6 modules
+    checks.add(checkJsDocAndEs6Modules);
+
+    if (options.needsTranspilationFrom(TYPESCRIPT)) {
+      checks.add(convertEs6TypedToEs6);
+    }
+
+    checks.add(gatherModuleMetadataPass);
+
+    if (options.enables(DiagnosticGroups.LINT_CHECKS)) {
+      checks.add(lintChecks);
+    }
+
+    if (options.closurePass && options.enables(DiagnosticGroups.LINT_CHECKS)) {
+      checks.add(checkRequiresAndProvidesSorted);
+    }
+
+    if (options.enables(DiagnosticGroups.MISSING_REQUIRE)
+        || options.enables(DiagnosticGroups.STRICT_MISSING_REQUIRE)
+        || options.enables(DiagnosticGroups.EXTRA_REQUIRE)) {
+      checks.add(checkRequires);
+    }
+
+    checks.add(checkVariableReferences);
+
+    if (options.getLanguageIn().toFeatureSet().has(FeatureSet.Feature.MODULES)) {
+      checks.add(rewriteGoogJsImports);
+      TranspilationPasses.addEs6ModulePass(checks, preprocessorSymbolTableFactory);
+    }
+
+    checks.add(checkStrictMode);
+
+    if (options.closurePass) {
+      checks.add(closureCheckModule);
+      checks.add(closureRewriteModule);
+    }
+
+    if (options.declaredGlobalExternsOnWindow) {
+      checks.add(declaredGlobalExternsOnWindow);
+    }
+
+    checks.add(checkSuper);
+
+    if (options.closurePass) {
+      checks.add(closureGoogScopeAliases);
+      checks.add(closureRewriteClass);
+    }
+
+    checks.add(checkSideEffects);
+
+    if (options.enables(DiagnosticGroups.MISSING_PROVIDE)) {
+      checks.add(checkProvides);
+    }
+
+    if (options.angularPass) {
+      checks.add(angularPass);
+    }
+
+    if (!options.generateExportsAfterTypeChecking && options.generateExports) {
+      checks.add(generateExports);
+    }
+
+    if (options.exportTestFunctions) {
+      checks.add(exportTestFunctions);
+    }
+
+    if (options.closurePass) {
+      checks.add(closurePrimitives);
+    }
+
+    // It's important that the PolymerPass run *after* the ClosurePrimitives and ChromePass rewrites
+    // and *before* the suspicious code checks. This is enforced in the assertValidOrder method.
+    if (options.polymerVersion != null) {
+      checks.add(polymerPass);
+    }
+
+    if (options.checkSuspiciousCode
+        || options.enables(DiagnosticGroups.GLOBAL_THIS)
+        || options.enables(DiagnosticGroups.DEBUGGER_STATEMENT_PRESENT)) {
+      checks.add(suspiciousCode);
+    }
+
+    if (options.closurePass && options.checkMissingGetCssNameLevel.isOn()) {
+      checks.add(closureCheckGetCssName);
+    }
+
+    if (options.syntheticBlockStartMarker != null) {
+      // This pass must run before the first fold constants pass.
+      checks.add(createSyntheticBlocks);
+    }
+
+    checks.add(checkVars);
+
+    if (options.inferConsts) {
+      checks.add(inferConsts);
+    }
+
+    if (options.computeFunctionSideEffects) {
+      checks.add(checkRegExp);
+    }
+
+    // This pass should run before types are assigned.
+    if (options.processObjectPropertyString) {
+      checks.add(objectPropertyStringPreprocess);
+    }
+
+    // It's important that the Dart super accessors pass run *before* es6ConvertSuper,
+    // which is a "late" ES6 pass. This is enforced in the assertValidOrder method.
+    if (options.dartPass && !options.getOutputFeatureSet().contains(ES6)) {
+      checks.add(dartSuperAccessorsPass);
+    }
+
+    // Passes running before this point should expect to see language features up to ES_2017.
+    checks.add(createEmptyPass(PassNames.BEFORE_ES_2017_TRANSPILATION));
+
+    TranspilationPasses.addPreTypecheckTranspilationPasses(checks, options);
+
+    if (options.rewritePolyfills && !options.checksOnly) {
+      TranspilationPasses.addRewritePolyfillPass(checks);
+    }
+
+    checks.add(injectRuntimeLibraries);
+    checks.add(createEmptyPass(PassNames.BEFORE_TYPE_CHECKING));
+
+    addTypeCheckerPasses(checks, options);
+
+    if (options.j2clPassMode.shouldAddJ2clPasses()) {
+      checks.add(j2clSourceFileChecker);
+    }
+
+    if (!options.disables(DiagnosticGroups.CHECK_USELESS_CODE)
+        || !options.disables(DiagnosticGroups.MISSING_RETURN)) {
+      checks.add(checkControlFlow);
+    }
+    
+    /* The AS compiler should have checked the same thing
+     * that CheckAccessControls checks.  CheckAccessControls
+     * also outputs false positives when compiling modules.
+
+    // CheckAccessControls only works if check types is on.
+    if (options.isTypecheckingEnabled()
+        && (!options.disables(DiagnosticGroups.ACCESS_CONTROLS)
+            || options.enables(DiagnosticGroups.CONSTANT_PROPERTY))) {
+      checks.add(checkAccessControls);
+    }
+     */
+
+    /* The AS compiler should have checked the same thing
+     * that CheckConsts checks.  CheckConsts
+     * also outputs false positives when compiling modules.
+    checks.add(checkConsts);
+     */
+
+    // Analyzer checks must be run after typechecking.
+    if (options.enables(DiagnosticGroups.ANALYZER_CHECKS) && options.isTypecheckingEnabled()) {
+      checks.add(analyzerChecks);
+    }
+
+    if (options.checkGlobalNamesLevel.isOn()) {
+      checks.add(checkGlobalNames);
+    }
+
+    if (!options.getConformanceConfigs().isEmpty()) {
+      checks.add(checkConformance);
+    }
+
+    // Replace 'goog.getCssName' before processing defines but after the
+    // other checks have been done.
+    if (options.closurePass && !options.shouldPreserveGoogLibraryPrimitives()) {
+      checks.add(closureReplaceGetCssName);
+    }
+
+    if (options.getTweakProcessing().isOn()) {
+      checks.add(processTweaks);
+    }
+
+    if (options.instrumentationTemplate != null || options.recordFunctionInformation) {
+      checks.add(computeFunctionNames);
+    }
+
+    if (options.checksOnly) {
+      // Run process defines here so that warnings/errors from that pass are emitted as part of
+      // checks.
+      // TODO(rluble): Split process defines into two stages, one that performs only checks to be
+      // run here, and the one that actually changes the AST that would run in the optimization
+      // phase.
+      checks.add(processDefines);
+    }
+
+    if (options.j2clPassMode.shouldAddJ2clPasses()) {
+      checks.add(j2clChecksPass);
+    }
+
+    if (options.shouldRunTypeSummaryChecksLate()) {
+      checks.add(generateIjs);
+    }
+
+    // When options.generateExportsAfterTypeChecking is true, run GenerateExports after
+    // both type checkers, not just after NTI.
+    if (options.generateExportsAfterTypeChecking && options.generateExports) {
+      checks.add(generateExports);
+    }
+
+    checks.add(createEmptyPass(PassNames.AFTER_STANDARD_CHECKS));
+
+    if (!options.checksOnly) {
+      // At this point all checks have been done.
+      // There's no need to complete transpilation if we're only running checks.
+      TranspilationPasses.addPostCheckTranspilationPasses(checks, options);
+
+      if (options.needsTranspilationFrom(ES6)) {
+        // This pass used to be necessary to make the typechecker happy with class-side inheritance.
+        // It's not necessary for typechecking now that class transpilation is post-typechecking,
+        // but it turned out to be necessary to avoid CollapseProperties breaking static inheritance
+        // TODO(b/116054203): try to only run this pass when property collapsing is enabled during
+        // the optimizations. Even better, find a way to get rid of this pass completely.
+        checks.add(convertStaticInheritance);
+      }
+    }
+
+    assertAllOneTimePasses(checks);
+    assertValidOrderForChecks(checks);
+
+    return checks;
+  }
+
+  @Override
+  protected List<PassFactory> getOptimizations() {
+    List<PassFactory> passes = new ArrayList<PassFactory>();
+
+    if (options.skipNonTranspilationPasses) {
+      return passes;
+    }
+
+    passes.add(removeWeakSources);
+
+    passes.add(garbageCollectChecks);
+
+    // i18n
+    // If you want to customize the compiler to use a different i18n pass,
+    // you can create a PassConfig that calls replacePassFactory
+    // to replace this.
+    if (options.replaceMessagesWithChromeI18n) {
+      passes.add(replaceMessagesForChrome);
+    } else if (options.messageBundle != null) {
+      passes.add(replaceMessages);
+    }
+
+    // Defines in code always need to be processed.
+    passes.add(processDefines);
+
+    if (options.getTweakProcessing().shouldStrip()
+        || !options.stripTypes.isEmpty()
+        || !options.stripNameSuffixes.isEmpty()
+        || !options.stripTypePrefixes.isEmpty()
+        || !options.stripNamePrefixes.isEmpty()) {
+      passes.add(stripCode);
+    }
+
+    passes.add(normalize);
+
+    // Create extern exports after the normalize because externExports depends on unique names.
+    if (options.isExternExportsEnabled() || options.externExportsPath != null) {
+      passes.add(externExports);
+    }
+
+    // Gather property names in externs so they can be queried by the
+    // optimizing passes.
+    passes.add(gatherExternProperties);
+
+    // Should be run before runtimeTypeCheck and instrumentForCoverage as they rewrite code that
+    // this pass expects to see.
+    if (options.j2clPassMode.shouldAddJ2clPasses()) {
+      passes.add(j2clPass);
+      passes.add(j2clUtilGetDefineRewriterPass);
+    }
+
+    if (options.instrumentForCoverage) {
+      passes.add(instrumentForCodeCoverage);
+    }
+
+    if (options.runtimeTypeCheck) {
+      passes.add(runtimeTypeCheck);
+    }
+
+    passes.add(createEmptyPass(PassNames.BEFORE_STANDARD_OPTIMIZATIONS));
+
+    if (options.replaceIdGenerators) {
+      passes.add(replaceIdGenerators);
+    }
+
+    // Optimizes references to the arguments variable.
+    if (options.optimizeArgumentsArray) {
+      passes.add(optimizeArgumentsArray);
+    }
+
+    // Abstract method removal works best on minimally modified code, and also
+    // only needs to run once.
+    if (options.closurePass && (options.removeAbstractMethods || options.removeClosureAsserts)) {
+      passes.add(closureCodeRemoval);
+    }
+
+    if (options.removeJ2clAsserts) {
+      passes.add(j2clAssertRemovalPass);
+    }
+
+    // Property disambiguation should only run once and needs to be done
+    // soon after type checking, both so that it can make use of type
+    // information and so that other passes can take advantage of the renamed
+    // properties.
+    if (options.disambiguatePrivateProperties) {
+      passes.add(disambiguatePrivateProperties);
+    }
+
+    assertAllOneTimePasses(passes);
+
+    // Inline aliases so that following optimizations don't have to understand alias chains.
+    if (options.shouldCollapseProperties()) {
+      passes.add(aggressiveInlineAliases);
+    }
+
+    // Inline getters/setters in J2CL classes so that Object.defineProperties() calls (resulting
+    // from desugaring) don't block class stripping.
+    if (options.j2clPassMode.shouldAddJ2clPasses() && options.shouldCollapseProperties()) {
+      // Relies on collapseProperties-triggered aggressive alias inlining.
+      passes.add(j2clPropertyInlinerPass);
+    }
+
+    // Collapsing properties can undo constant inlining, so we do this before
+    // the main optimization loop.
+    if (options.shouldCollapseProperties()) {
+      passes.add(collapseProperties);
+    }
+
+    if (options.inferConsts) {
+      passes.add(inferConsts);
+    }
+
+    // TODO(mlourenco): Ideally this would be in getChecks() instead of getOptimizations(). But
+    // for that it needs to understand constant properties as well. See b/31301233#10.
+    // Needs to happen after inferConsts and collapseProperties. Detects whether invocations of
+    // the method goog.string.Const.from are done with an argument which is a string literal.
+    passes.add(checkConstParams);
+
+    // Running RemoveUnusedCode before disambiguate properties allows disambiguate properties to be
+    // more effective if code that would prevent disambiguation can be removed.
+    // TODO(b/66971163): Rename options since we're not actually using smartNameRemoval here now.
+    if (options.extraSmartNameRemoval && options.smartNameRemoval) {
+
+      // These passes remove code that is dead because of define flags.
+      // If the dead code is weakly typed, running these passes before property
+      // disambiguation results in more code removal.
+      // The passes are one-time on purpose. (The later runs are loopable.)
+      if (options.foldConstants && (options.inlineVariables || options.inlineLocalVariables)) {
+        passes.add(earlyInlineVariables);
+        passes.add(earlyPeepholeOptimizations);
+      }
+
+      passes.add(removeUnusedCodeOnce);
+    }
+
+    // RewritePolyfills is overly generous in the polyfills it adds.  After type
+    // checking and early smart name removal, we can use the new type information
+    // to figure out which polyfilled prototype methods are actually called, and
+    // which were "false alarms" (i.e. calling a method of the same name on a
+    // user-provided class).  We also remove any polyfills added by code that
+    // was smart-name-removed.  This is a one-time pass, since it does not work
+    // after inlining - we do not attempt to aggressively remove polyfills used
+    // by code that is only flow-sensitively dead.
+    if (options.rewritePolyfills) {
+      passes.add(removeUnusedPolyfills);
+    }
+
+    // Property disambiguation should only run once and needs to be done
+    // soon after type checking, both so that it can make use of type
+    // information and so that other passes can take advantage of the renamed
+    // properties.
+    if (options.shouldDisambiguateProperties() && options.isTypecheckingEnabled()) {
+      passes.add(disambiguateProperties);
+    }
+
+    if (options.computeFunctionSideEffects) {
+      passes.add(markPureFunctions);
+    } else if (options.markNoSideEffectCalls) {
+      // TODO(user) The properties that this pass adds to CALL and NEW
+      // AST nodes increase the AST's in-memory size.  Given that we are
+      // already running close to our memory limits, we could run into
+      // trouble if we end up using the @nosideeffects annotation a lot
+      // or compute @nosideeffects annotations by looking at function
+      // bodies.  It should be easy to propagate @nosideeffects
+      // annotations as part of passes that depend on this property and
+      // store the result outside the AST (which would allow garbage
+      // collection once the pass is done).
+      passes.add(markNoSideEffectCalls);
+    }
+
+    if (options.smartNameRemoval) {
+      passes.addAll(getCodeRemovingPasses());
+      // TODO(b/66971163): Remove this early loop or rename the option that enables it
+      // to something more appropriate.
+    }
+
+    // This needs to come after the inline constants pass, which is run within
+    // the code removing passes.
+    if (options.closurePass) {
+      passes.add(closureOptimizePrimitives);
+    }
+
+    // ReplaceStrings runs after CollapseProperties in order to simplify
+    // pulling in values of constants defined in enums structures. It also runs
+    // after disambiguate properties and smart name removal so that it can
+    // correctly identify logging types and can replace references to string
+    // expressions.
+    if (!options.replaceStringsFunctionDescriptions.isEmpty()) {
+      passes.add(replaceStrings);
+    }
+
+    // TODO(user): This forces a first crack at crossChunkCodeMotion
+    // before devirtualization. Once certain functions are devirtualized,
+    // it confuses crossChunkCodeMotion ability to recognized that
+    // it is recursive.
+
+    // TODO(user): This is meant for a temporary quick win.
+    // In the future, we might want to improve our analysis in
+    // CrossChunkCodeMotion so we don't need to do this.
+    if (options.shouldRunCrossChunkCodeMotion()) {
+      passes.add(crossModuleCodeMotion);
+    }
+
+    // Method devirtualization benefits from property disambiguation so
+    // it should run after that pass but before passes that do
+    // optimizations based on global names (like cross module code motion
+    // and inline functions).  Smart Name Removal does better if run before
+    // this pass.
+    if (options.devirtualizePrototypeMethods) {
+      passes.add(devirtualizePrototypeMethods);
+    }
+
+    if (options.customPasses != null) {
+      passes.add(getCustomPasses(
+          CustomPassExecutionTime.BEFORE_OPTIMIZATION_LOOP));
+    }
+
+    passes.add(createEmptyPass(PassNames.BEFORE_MAIN_OPTIMIZATIONS));
+
+    // Because FlowSensitiveInlineVariables does not operate on the global scope due to compilation
+    // time, we need to run it once before InlineFunctions so that we don't miss inlining
+    // opportunities when a function will be inlined into the global scope.
+    if (options.inlineVariables || options.inlineLocalVariables) {
+      passes.add(flowSensitiveInlineVariables);
+    }
+
+    passes.addAll(getMainOptimizationLoop());
+    passes.add(createEmptyPass(PassNames.AFTER_MAIN_OPTIMIZATIONS));
+
+    passes.add(createEmptyPass("beforeModuleMotion"));
+
+    if (options.shouldRunCrossChunkCodeMotion()) {
+      passes.add(crossModuleCodeMotion);
+    }
+
+    if (options.shouldRunCrossChunkMethodMotion()) {
+      passes.add(crossModuleMethodMotion);
+    }
+
+    passes.add(createEmptyPass("afterModuleMotion"));
+
+    // Some optimizations belong outside the loop because running them more
+    // than once would either have no benefit or be incorrect.
+    if (options.customPasses != null) {
+      passes.add(getCustomPasses(
+          CustomPassExecutionTime.AFTER_OPTIMIZATION_LOOP));
+    }
+
+    if (options.inlineVariables || options.inlineLocalVariables) {
+      passes.add(flowSensitiveInlineVariables);
+
+      // After inlining some of the variable uses, some variables are unused.
+      // Re-run remove unused vars to clean it up.
+      if (shouldRunRemoveUnusedCode()) {
+        passes.add(removeUnusedCodeOnce);
+      }
+    }
+
+    if (options.collapseAnonymousFunctions) {
+      passes.add(collapseAnonymousFunctions);
+    }
+
+    // Move functions before extracting prototype member declarations.
+    if (options.moveFunctionDeclarations
+        // renamePrefixNamescape relies on moveFunctionDeclarations
+        // to preserve semantics.
+        || options.renamePrefixNamespace != null) {
+      passes.add(moveFunctionDeclarations);
+    }
+
+    if (options.anonymousFunctionNaming == AnonymousFunctionNamingPolicy.MAPPED) {
+      passes.add(nameMappedAnonymousFunctions);
+    }
+
+    // The mapped name anonymous function pass makes use of information that
+    // the extract prototype member declarations pass removes so the former
+    // happens before the latter.
+    if (options.extractPrototypeMemberDeclarations != ExtractPrototypeMemberDeclarationsMode.OFF) {
+      passes.add(extractPrototypeMemberDeclarations);
+    }
+
+    if (options.shouldAmbiguateProperties()
+        && options.propertyRenaming == PropertyRenamingPolicy.ALL_UNQUOTED
+        && options.isTypecheckingEnabled()) {
+      passes.add(ambiguateProperties);
+    }
+
+    if (options.propertyRenaming == PropertyRenamingPolicy.ALL_UNQUOTED) {
+      passes.add(renameProperties);
+    }
+
+    // Reserve global names added to the "windows" object.
+    if (options.reserveRawExports) {
+      passes.add(gatherRawExports);
+    }
+
+    // This comes after property renaming because quoted property names must
+    // not be renamed.
+    if (options.convertToDottedProperties) {
+      passes.add(convertToDottedProperties);
+    }
+
+    // Property renaming must happen before this pass runs since this
+    // pass may convert dotted properties into quoted properties.  It
+    // is beneficial to run before alias strings, alias keywords and
+    // variable renaming.
+    if (options.rewriteFunctionExpressions) {
+      passes.add(rewriteFunctionExpressions);
+    }
+
+    // This comes after converting quoted property accesses to dotted property
+    // accesses in order to avoid aliasing property names.
+    if (!options.aliasableStrings.isEmpty() || options.aliasAllStrings) {
+      passes.add(aliasStrings);
+    }
+
+    if (options.coalesceVariableNames) {
+      // Passes after this point can no longer depend on normalized AST
+      // assumptions because the code is marked as un-normalized
+      passes.add(coalesceVariableNames);
+
+      // coalesceVariables creates identity assignments and more redundant code
+      // that can be removed, rerun the peephole optimizations to clean them
+      // up.
+      if (options.foldConstants) {
+        passes.add(peepholeOptimizationsOnce);
+      }
+    }
+
+    // Passes after this point can no longer depend on normalized AST assumptions.
+    passes.add(markUnnormalized);
+
+    if (options.collapseVariableDeclarations) {
+      passes.add(exploitAssign);
+      passes.add(collapseVariableDeclarations);
+    }
+
+    // This pass works best after collapseVariableDeclarations.
+    passes.add(denormalize);
+
+    if (options.instrumentationTemplate != null) {
+      passes.add(instrumentFunctions);
+    }
+
+    if (options.variableRenaming != VariableRenamingPolicy.ALL) {
+      // If we're leaving some (or all) variables with their old names,
+      // then we need to undo any of the markers we added for distinguishing
+      // local variables ("x" -> "x$jscomp$1").
+      passes.add(invertContextualRenaming);
+    }
+
+    if (options.variableRenaming != VariableRenamingPolicy.OFF) {
+      passes.add(renameVars);
+    }
+
+    // This pass should run after names stop changing.
+    if (options.processObjectPropertyString) {
+      passes.add(objectPropertyStringPostprocess);
+    }
+
+    if (options.labelRenaming) {
+      passes.add(renameLabels);
+    }
+
+    if (options.foldConstants) {
+      passes.add(latePeepholeOptimizations);
+    }
+
+    if (options.anonymousFunctionNaming == AnonymousFunctionNamingPolicy.UNMAPPED) {
+      passes.add(nameUnmappedAnonymousFunctions);
+    }
+
+    if (protectHiddenSideEffects) {
+      passes.add(stripSideEffectProtection);
+    }
+
+    if (options.renamePrefixNamespace != null) {
+      if (!GLOBAL_SYMBOL_NAMESPACE_PATTERN.matcher(
+          options.renamePrefixNamespace).matches()) {
+        throw new IllegalArgumentException(
+            "Illegal character in renamePrefixNamespace name: "
+            + options.renamePrefixNamespace);
+      }
+      passes.add(rescopeGlobalSymbols);
+    }
+
+    // Safety checks
+    passes.add(checkAstValidity);
+    passes.add(varCheckValidity);
+
+    // Raise to ES6, if allowed
+    if (options.getOutputFeatureSet().contains(ES6)) {
+      passes.add(optimizeToEs6);
+    }
+
+    assertValidOrderForOptimizations(passes);
+    return passes;
+  }
+
+  /** Creates the passes for the main optimization loop. */
+  private List<PassFactory> getMainOptimizationLoop() {
+    List<PassFactory> passes = new ArrayList<PassFactory>();
+    if (options.inlineGetters) {
+      passes.add(inlineSimpleMethods);
+    }
+
+    passes.addAll(getCodeRemovingPasses());
+
+    if (options.getInlineFunctionsLevel() != Reach.NONE) {
+      passes.add(inlineFunctions);
+    }
+
+    if (options.shouldInlineProperties() && options.isTypecheckingEnabled()) {
+      passes.add(inlineProperties);
+    }
+
+    if (options.removeUnusedVars || options.removeUnusedLocalVars) {
+      if (options.deadAssignmentElimination) {
+        passes.add(deadAssignmentsElimination);
+
+        // The Polymer source is usually not included in the compilation, but it creates
+        // getters/setters for many properties in compiled code. Dead property assignment
+        // elimination is only safe when it knows about getters/setters. Therefore, we skip
+        // it if the polymer pass is enabled.
+        if (options.polymerVersion == null) {
+          passes.add(deadPropertyAssignmentElimination);
+        }
+      }
+    }
+
+    if (options.optimizeCalls) {
+      passes.add(optimizeCalls);
+    }
+
+    if (options.j2clPassMode.shouldAddJ2clPasses()) {
+      passes.add(j2clConstantHoisterPass);
+      passes.add(j2clClinitPass);
+    }
+
+    assertAllLoopablePasses(passes);
+    return passes;
+  }
+
+  /** Creates several passes aimed at removing code. */
+  private List<PassFactory> getCodeRemovingPasses() {
+    List<PassFactory> passes = new ArrayList<PassFactory>();
+    if (options.collapseObjectLiterals) {
+      passes.add(collapseObjectLiterals);
+    }
+
+    if (options.inlineVariables || options.inlineLocalVariables) {
+      passes.add(inlineVariables);
+    } else if (options.inlineConstantVars) {
+      passes.add(inlineConstants);
+    }
+
+    if (options.foldConstants) {
+      passes.add(peepholeOptimizations);
+    }
+
+    if (options.removeDeadCode) {
+      passes.add(removeUnreachableCode);
+    }
+
+    if (shouldRunRemoveUnusedCode()) {
+      passes.add(removeUnusedCode);
+    }
+
+    assertAllLoopablePasses(passes);
+    return passes;
+  }
+
+  private boolean shouldRunRemoveUnusedCode() {
+    return options.removeUnusedVars
+        || options.removeUnusedLocalVars
+        || options.removeUnusedPrototypeProperties
+        || options.isRemoveUnusedClassProperties()
+        || options.isRemoveUnusedConstructorProperties();
+  }
+
+  private final HotSwapPassFactory checkSideEffects =
+      new HotSwapPassFactory("checkSideEffects") {
+        @Override
+        protected HotSwapCompilerPass create(final AbstractCompiler compiler) {
+          return new CheckSideEffects(
+              compiler, options.checkSuspiciousCode, protectHiddenSideEffects);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Removes the "protector" functions that were added by CheckSideEffects. */
+  private final PassFactory stripSideEffectProtection =
+      new PassFactory(PassNames.STRIP_SIDE_EFFECT_PROTECTION, true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          return new CheckSideEffects.StripProtection(compiler);
+        }
+
+        @Override
+        public FeatureSet featureSet() {
+          return FeatureSet.latest();
+        }
+      };
+
+  /** Checks for code that is probably wrong (such as stray expressions). */
+  private final HotSwapPassFactory suspiciousCode =
+      new HotSwapPassFactory("suspiciousCode") {
+        @Override
+        protected HotSwapCompilerPass create(final AbstractCompiler compiler) {
+          List<Callback> sharedCallbacks = new ArrayList<Callback>();
+          if (options.checkSuspiciousCode) {
+            sharedCallbacks.add(new CheckSuspiciousCode());
+            sharedCallbacks.add(new CheckDuplicateCase(compiler));
+          }
+
+          if (options.enables(DiagnosticGroups.GLOBAL_THIS)) {
+            sharedCallbacks.add(new CheckGlobalThis(compiler));
+          }
+
+          if (options.enables(DiagnosticGroups.DEBUGGER_STATEMENT_PRESENT)) {
+            sharedCallbacks.add(new CheckDebuggerStatement(compiler));
+          }
+
+          return combineChecks(compiler, sharedCallbacks);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Verify that all the passes are one-time passes. */
+  private static void assertAllOneTimePasses(List<PassFactory> passes) {
+    for (PassFactory pass : passes) {
+      checkState(pass.isOneTimePass());
+    }
+  }
+
+  /** Verify that all the passes are multi-run passes. */
+  private static void assertAllLoopablePasses(List<PassFactory> passes) {
+    for (PassFactory pass : passes) {
+      checkState(!pass.isOneTimePass());
+    }
+  }
+
+  /**
+   * Checks that {@code pass1} comes before {@code pass2} in {@code passList}, if both are present.
+   */
+  private void assertPassOrder(
+      List<PassFactory> passList, PassFactory pass1, PassFactory pass2, String msg) {
+    int pass1Index = passList.indexOf(pass1);
+    int pass2Index = passList.indexOf(pass2);
+    if (pass1Index != -1 && pass2Index != -1) {
+      checkState(pass1Index < pass2Index, msg);
+    }
+  }
+
+  /**
+   * Certain checks need to run in a particular order. For example, the PolymerPass
+   * will not work correctly unless it runs after the goog.provide() processing.
+   * This enforces those constraints.
+   * @param checks The list of check passes
+   */
+  private void assertValidOrderForChecks(List<PassFactory> checks) {
+    assertPassOrder(
+        checks,
+        chromePass,
+        checkJsDocAndEs6Modules,
+        "The ChromePass must run before after JsDoc and Es6 module checking.");
+    assertPassOrder(
+        checks,
+        closureRewriteModule,
+        processDefines,
+        "Must rewrite goog.module before processing @define's, so that @defines in modules work.");
+    assertPassOrder(
+        checks,
+        closurePrimitives,
+        polymerPass,
+        "The Polymer pass must run after goog.provide processing.");
+    assertPassOrder(
+        checks,
+        chromePass,
+        polymerPass,
+        "The Polymer pass must run after ChromePass processing.");
+    assertPassOrder(
+        checks,
+        polymerPass,
+        suspiciousCode,
+        "The Polymer pass must run before suspiciousCode processing.");
+    assertPassOrder(
+        checks,
+        dartSuperAccessorsPass,
+        TranspilationPasses.es6ConvertSuper,
+        "The Dart super accessors pass must run before ES6->ES3 super lowering.");
+
+    if (checks.contains(closureGoogScopeAliases)) {
+      checkState(
+          checks.contains(checkVariableReferences),
+          "goog.scope processing requires variable checking");
+    }
+    assertPassOrder(
+        checks,
+        checkVariableReferences,
+        closureGoogScopeAliases,
+        "Variable checking must happen before goog.scope processing.");
+
+    assertPassOrder(
+        checks,
+        gatherModuleMetadataPass,
+        closureCheckModule,
+        "Need to gather module metadata before checking closure modules.");
+  }
+
+  /**
+   * Certain optimizations need to run in a particular order. For example, OptimizeCalls must run
+   * before RemoveSuperMethodsPass, because the former can invalidate assumptions in the latter.
+   * This enforces those constraints.
+   * @param optimizations The list of optimization passes
+   */
+  private void assertValidOrderForOptimizations(List<PassFactory> optimizations) {
+    assertPassOrder(
+        optimizations,
+        processDefines,
+        j2clUtilGetDefineRewriterPass,
+        "J2CL define re-writing should be done after processDefines since it relies on "
+            + "collectDefines which has side effects.");
+  }
+
+  /** Checks that all constructed classes are goog.require()d. */
+  private final HotSwapPassFactory checkRequires =
+      new HotSwapPassFactory("checkMissingAndExtraRequires") {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new CheckMissingAndExtraRequires(
+              compiler, CheckMissingAndExtraRequires.Mode.FULL_COMPILE);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Makes sure @constructor is paired with goog.provides(). */
+  private final HotSwapPassFactory checkProvides =
+      new HotSwapPassFactory("checkProvides") {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new CheckProvides(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  private static final DiagnosticType GENERATE_EXPORTS_ERROR =
+      DiagnosticType.error(
+          "JSC_GENERATE_EXPORTS_ERROR",
+          "Exports can only be generated if export symbol/property functions are set.");
+
+  /** Verifies JSDoc annotations are used properly and checks for ES6 modules. */
+  private final HotSwapPassFactory checkJsDocAndEs6Modules =
+      new HotSwapPassFactory("checkJsDocAndEs6Modules") {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          ImmutableList.Builder<Callback> callbacks =
+              ImmutableList.<Callback>builder()
+                  .add(new CheckJSDoc(compiler))
+                  .add(new Es6CheckModule(compiler));
+          return combineChecks(compiler, callbacks.build());
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return FeatureSet.latest();
+        }
+      };
+
+  /** Generates exports for @export annotations. */
+  private final PassFactory generateExports =
+      new PassFactory(PassNames.GENERATE_EXPORTS, true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          CodingConvention convention = compiler.getCodingConvention();
+          if (convention.getExportSymbolFunction() != null
+              && convention.getExportPropertyFunction() != null) {
+            final GenerateExports pass =
+                new GenerateExports(
+                    compiler,
+                    options.exportLocalPropertyDefinitions,
+                    convention.getExportSymbolFunction(),
+                    convention.getExportPropertyFunction());
+            return new CompilerPass() {
+              @Override
+              public void process(Node externs, Node root) {
+                pass.process(externs, root);
+                compiler.addExportedNames(pass.getExportedVariableNames());
+              }
+            };
+          } else {
+            return new ErrorPass(compiler, GENERATE_EXPORTS_ERROR);
+          }
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES2018;
+        }
+      };
+
+  private final PassFactory generateIjs =
+      new PassFactory("generateIjs", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new ConvertToTypedInterface(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Generates exports for functions associated with JsUnit. */
+  private final PassFactory exportTestFunctions =
+      new PassFactory(PassNames.EXPORT_TEST_FUNCTIONS, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          CodingConvention convention = compiler.getCodingConvention();
+          if (convention.getExportSymbolFunction() != null) {
+            return new ExportTestFunctions(
+                compiler,
+                convention.getExportSymbolFunction(),
+                convention.getExportPropertyFunction());
+          } else {
+            return new ErrorPass(compiler, GENERATE_EXPORTS_ERROR);
+          }
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Raw exports processing pass. */
+  private final PassFactory gatherRawExports =
+      new PassFactory(PassNames.GATHER_RAW_EXPORTS, true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          final GatherRawExports pass = new GatherRawExports(compiler);
+
+          return new CompilerPass() {
+            @Override
+            public void process(Node externs, Node root) {
+              pass.process(externs, root);
+              compiler.addExportedNames(pass.getExportedVariableNames());
+            }
+          };
+        }
+
+        @Override
+        public FeatureSet featureSet() {
+          // Should be FeatureSet.latest() since it's a trivial pass, but must match "normalize"
+          // TODO(johnlenz): Update this and normalize to latest()
+          return ES8_MODULES;
+        }
+      };
+
+  /** Closure pre-processing pass. */
+  private final HotSwapPassFactory closurePrimitives =
+      new HotSwapPassFactory("closurePrimitives") {
+        @SuppressWarnings("deprecation")
+		@Override
+        protected HotSwapCompilerPass create(final AbstractCompiler compiler) {
+          preprocessorSymbolTableFactory.maybeInitialize(compiler);
+          final ProcessClosurePrimitivesWithModuleSupport pass =
+              new ProcessClosurePrimitivesWithModuleSupport(
+                  compiler,
+                  preprocessorSymbolTableFactory.getInstanceOrNull(),
+                  options.brokenClosureRequiresLevel,
+                  options.shouldPreservesGoogProvidesAndRequires());
+
+          return new HotSwapCompilerPass() {
+            @Override
+            public void process(Node externs, Node root) {
+              pass.process(externs, root);
+              compiler.addExportedNames(pass.getExportedVariableNames());
+            }
+
+            @Override
+            public void hotSwapScript(Node scriptRoot, Node originalRoot) {
+              pass.hotSwapScript(scriptRoot, originalRoot);
+            }
+          };
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Process AngularJS-specific annotations. */
+  private final HotSwapPassFactory angularPass =
+      new HotSwapPassFactory(PassNames.ANGULAR_PASS) {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new AngularPass(compiler);
+        }
+
+        @Override
+        public FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /**
+   * The default i18n pass. A lot of the options are not configurable, because ReplaceMessages has a
+   * lot of legacy logic.
+   */
+  private final PassFactory replaceMessages =
+      new PassFactory(PassNames.REPLACE_MESSAGES, true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          return new ReplaceMessages(
+              compiler,
+              options.messageBundle,
+              /* warn about message dupes */
+              true,
+              /* allow messages with goog.getMsg */
+              JsMessage.Style.CLOSURE,
+              /* if we can't find a translation, don't worry about it. */
+              false);
+        }
+
+        @Override
+        public FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  private final PassFactory replaceMessagesForChrome =
+      new PassFactory(PassNames.REPLACE_MESSAGES, true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          return new ReplaceMessagesForChrome(
+              compiler,
+              new GoogleJsMessageIdGenerator(options.tcProjectId),
+              /* warn about message dupes */
+              true,
+              /* allow messages with goog.getMsg */
+              JsMessage.Style.CLOSURE);
+        }
+
+        @Override
+        public FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Applies aliases and inlines goog.scope. */
+  private final HotSwapPassFactory closureGoogScopeAliases =
+      new HotSwapPassFactory("closureGoogScopeAliases") {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          preprocessorSymbolTableFactory.maybeInitialize(compiler);
+          return new ScopedAliases(
+              compiler,
+              preprocessorSymbolTableFactory.getInstanceOrNull(),
+              options.getAliasTransformationHandler());
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  private final PassFactory injectRuntimeLibraries =
+      new PassFactory("InjectRuntimeLibraries", true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          return new InjectRuntimeLibraries(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES2018;
+        }
+      };
+
+  /** Desugars ES6_TYPED features into ES6 code. */
+  final HotSwapPassFactory convertEs6TypedToEs6 =
+      new HotSwapPassFactory("convertEs6Typed") {
+        @Override
+        protected HotSwapCompilerPass create(final AbstractCompiler compiler) {
+          return new Es6TypedToEs6Converter(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return TYPESCRIPT;
+        }
+      };
+
+  private final PassFactory convertStaticInheritance =
+      new PassFactory("Es6StaticInheritance", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new Es6ToEs3ClassSideInheritance(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return TYPE_CHECK_SUPPORTED;
+        }
+      };
+
+  private final PassFactory inlineTypeAliases =
+      new PassFactory(PassNames.INLINE_TYPE_ALIASES, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new InlineAliases(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES2018;
+        }
+      };
+
+  /** Inlines type aliases if they are explicitly or effectively const. */
+  private final PassFactory aggressiveInlineAliases =
+      new PassFactory("aggressiveInlineAliases", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new AggressiveInlineAliases(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  private final PassFactory removeWeakSources =
+      new PassFactory("removeWeakSources", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new RemoveWeakSources(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return FeatureSet.latest();
+        }
+      };
+
+  private final PassFactory declaredGlobalExternsOnWindow =
+      new PassFactory(PassNames.DECLARED_GLOBAL_EXTERNS_ON_WINDOW, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new DeclaredGlobalExternsOnWindow(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Rewrites goog.defineClass */
+  private final HotSwapPassFactory closureRewriteClass =
+      new HotSwapPassFactory(PassNames.CLOSURE_REWRITE_CLASS) {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new ClosureRewriteClass(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Checks of correct usage of goog.module */
+  private final HotSwapPassFactory closureCheckModule =
+      new HotSwapPassFactory("closureCheckModule") {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new ClosureCheckModule(compiler, compiler.getModuleMetadataMap());
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Rewrites goog.module */
+  private final HotSwapPassFactory closureRewriteModule =
+      new HotSwapPassFactory("closureRewriteModule") {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          preprocessorSymbolTableFactory.maybeInitialize(compiler);
+          maybeInitializeModuleRewriteState();
+          return new ClosureRewriteModule(
+              compiler, preprocessorSymbolTableFactory.getInstanceOrNull(), moduleRewriteState);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Rewrite imports for Closure Library's goog.js file to global goog references. */
+  private final HotSwapPassFactory rewriteGoogJsImports =
+      new HotSwapPassFactory("rewriteGoogJsImports") {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new RewriteGoogJsImports(compiler, RewriteGoogJsImports.Mode.LINT_AND_REWRITE);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Checks that CSS class names are wrapped in goog.getCssName */
+  private final PassFactory closureCheckGetCssName =
+      new PassFactory("closureCheckGetCssName", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new CheckMissingGetCssName(
+              compiler,
+              options.checkMissingGetCssNameLevel,
+              options.checkMissingGetCssNameBlacklist);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /**
+   * Processes goog.getCssName. The cssRenamingMap is used to lookup replacement values for the
+   * classnames. If null, the raw class names are inlined.
+   */
+  private final PassFactory closureReplaceGetCssName =
+      new PassFactory("closureReplaceGetCssName", true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          return new CompilerPass() {
+            @Override
+            public void process(Node externs, Node jsRoot) {
+              Map<String, Integer> newCssNames = null;
+              if (options.gatherCssNames) {
+                newCssNames = new HashMap<String, Integer>();
+              }
+              ReplaceCssNames pass =
+                  new ReplaceCssNames(compiler, newCssNames, options.cssRenamingWhitelist);
+              pass.process(externs, jsRoot);
+              compiler.setCssNames(newCssNames);
+            }
+          };
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES2018;
+        }
+      };
+
+  /**
+   * Creates synthetic blocks to prevent FoldConstants from moving code past markers in the source.
+   */
+  private final PassFactory createSyntheticBlocks =
+      new PassFactory("createSyntheticBlocks", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new CreateSyntheticBlocks(
+              compiler, options.syntheticBlockStartMarker, options.syntheticBlockEndMarker);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  private final PassFactory earlyPeepholeOptimizations =
+      new PassFactory("earlyPeepholeOptimizations", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          List<AbstractPeepholeOptimization> peepholeOptimizations = new ArrayList<AbstractPeepholeOptimization>();
+          peepholeOptimizations.add(new PeepholeRemoveDeadCode());
+          if (compiler.getOptions().j2clPassMode.shouldAddJ2clPasses()) {
+            peepholeOptimizations.add(new J2clEqualitySameRewriterPass());
+          }
+          return new PeepholeOptimizationsPass(compiler, getName(), peepholeOptimizations);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  private final PassFactory earlyInlineVariables =
+      new PassFactory("earlyInlineVariables", true) {
+    @Override
+    protected CompilerPass create(AbstractCompiler compiler) {
+      InlineVariables.Mode mode;
+      if (options.inlineVariables) {
+        mode = InlineVariables.Mode.ALL;
+      } else if (options.inlineLocalVariables) {
+        mode = InlineVariables.Mode.LOCALS_ONLY;
+      } else {
+        throw new IllegalStateException("No variable inlining option set.");
+      }
+      return new InlineVariables(compiler, mode, true);
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return ES8_MODULES;
+    }
+  };
+
+  /** Various peephole optimizations. */
+  private static CompilerPass createPeepholeOptimizationsPass(
+      AbstractCompiler compiler, String passName) {
+    final boolean late = false;
+    final boolean useTypesForOptimization = compiler.getOptions().useTypesForLocalOptimization;
+    List<AbstractPeepholeOptimization> optimizations = new ArrayList<AbstractPeepholeOptimization>();
+    optimizations.add(new MinimizeExitPoints());
+    optimizations.add(new PeepholeMinimizeConditions(late));
+    optimizations.add(new PeepholeSubstituteAlternateSyntax(late));
+    optimizations.add(new PeepholeReplaceKnownMethods(late, useTypesForOptimization));
+    optimizations.add(new PeepholeRemoveDeadCode());
+    if (compiler.getOptions().j2clPassMode.shouldAddJ2clPasses()) {
+      optimizations.add(new J2clEqualitySameRewriterPass());
+      optimizations.add(new J2clStringValueOfRewriterPass());
+    }
+    optimizations.add(new PeepholeFoldConstants(late, useTypesForOptimization));
+    optimizations.add(new PeepholeCollectPropertyAssignments());
+    return new PeepholeOptimizationsPass(compiler, passName, optimizations);
+  }
+
+  /** Various peephole optimizations. */
+  private final PassFactory peepholeOptimizations =
+      new PassFactory(PassNames.PEEPHOLE_OPTIMIZATIONS, false /* oneTimePass */) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return createPeepholeOptimizationsPass(compiler, getName());
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Various peephole optimizations. */
+  private final PassFactory peepholeOptimizationsOnce =
+      new PassFactory(PassNames.PEEPHOLE_OPTIMIZATIONS, true /* oneTimePass */) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return createPeepholeOptimizationsPass(compiler, getName());
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Same as peepholeOptimizations but aggressively merges code together */
+  private final PassFactory latePeepholeOptimizations =
+      new PassFactory("latePeepholeOptimizations", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          final boolean late = true;
+          final boolean useTypesForOptimization = options.useTypesForLocalOptimization;
+          return new PeepholeOptimizationsPass(
+              compiler,
+              getName(),
+              new StatementFusion(options.aggressiveFusion),
+              new PeepholeRemoveDeadCode(),
+              new PeepholeMinimizeConditions(late),
+              new PeepholeSubstituteAlternateSyntax(late),
+              new PeepholeReplaceKnownMethods(late, useTypesForOptimization),
+              new PeepholeFoldConstants(late, useTypesForOptimization),
+              new PeepholeReorderConstantExpression());
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Checks that all variables are defined. */
+  private final HotSwapPassFactory checkVars =
+      new HotSwapPassFactory(PassNames.CHECK_VARS) {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new VarCheck(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Infers constants. */
+  private final PassFactory inferConsts =
+      new PassFactory(PassNames.INFER_CONSTS, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new InferConsts(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Checks for RegExp references. */
+  private final PassFactory checkRegExp =
+      new PassFactory(PassNames.CHECK_REG_EXP, true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          final CheckRegExp pass = new CheckRegExp(compiler);
+
+          return new CompilerPass() {
+            @Override
+            public void process(Node externs, Node root) {
+              pass.process(externs, root);
+              compiler.setHasRegExpGlobalReferences(pass.isGlobalRegExpPropertiesUsed());
+            }
+          };
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Checks that references to variables look reasonable. */
+  private final HotSwapPassFactory checkVariableReferencesForTranspileOnly =
+      new HotSwapPassFactory(PassNames.CHECK_VARIABLE_REFERENCES) {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new VariableReferenceCheck(compiler, true);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Checks that references to variables look reasonable. */
+  private final HotSwapPassFactory checkVariableReferences =
+      new HotSwapPassFactory(PassNames.CHECK_VARIABLE_REFERENCES) {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new VariableReferenceCheck(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Checks that references to variables look reasonable. */
+  private final HotSwapPassFactory checkSuper =
+      new HotSwapPassFactory("checkSuper") {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new CheckSuper(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Pre-process goog.testing.ObjectPropertyString. */
+  private final PassFactory objectPropertyStringPreprocess =
+      new PassFactory("ObjectPropertyStringPreprocess", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new ObjectPropertyStringPreprocess(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Creates a typed scope and adds types to the type registry. */
+  final HotSwapPassFactory resolveTypes =
+      new HotSwapPassFactory(PassNames.RESOLVE_TYPES) {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new GlobalTypeResolver(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return TYPE_CHECK_SUPPORTED;
+        }
+      };
+
+  /** Clears the typed scope when we're done. */
+  private final PassFactory clearTypedScopePass =
+      new PassFactory("clearTypedScopePass", true) {
+    @Override
+    protected CompilerPass create(AbstractCompiler compiler) {
+      return new ClearTypedScope();
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return FeatureSet.latest();
+    }
+  };
+
+  /** Runs type inference. */
+  final HotSwapPassFactory inferTypes =
+      new HotSwapPassFactory(PassNames.INFER_TYPES) {
+        @Override
+        protected HotSwapCompilerPass create(final AbstractCompiler compiler) {
+          return new HotSwapCompilerPass() {
+            @Override
+            public void process(Node externs, Node root) {
+              checkNotNull(topScope);
+              checkNotNull(getTypedScopeCreator());
+
+              makeTypeInference(compiler).process(externs, root);
+            }
+
+            @Override
+            public void hotSwapScript(Node scriptRoot, Node originalRoot) {
+              makeTypeInference(compiler).inferAllScopes(scriptRoot);
+            }
+          };
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return TYPE_CHECK_SUPPORTED;
+        }
+      };
+
+  private final HotSwapPassFactory inferJsDocInfo =
+      new HotSwapPassFactory("inferJsDocInfo") {
+        @Override
+        protected HotSwapCompilerPass create(final AbstractCompiler compiler) {
+          return new HotSwapCompilerPass() {
+            @Override
+            public void process(Node externs, Node root) {
+              checkNotNull(topScope);
+              checkNotNull(getTypedScopeCreator());
+
+              makeInferJsDocInfo(compiler).process(externs, root);
+            }
+
+            @Override
+            public void hotSwapScript(Node scriptRoot, Node originalRoot) {
+              makeInferJsDocInfo(compiler).hotSwapScript(scriptRoot, originalRoot);
+            }
+          };
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return TYPE_CHECK_SUPPORTED;
+        }
+      };
+
+  /** Checks type usage */
+  private final HotSwapPassFactory checkTypes =
+      new HotSwapPassFactory(PassNames.CHECK_TYPES) {
+        @Override
+        protected HotSwapCompilerPass create(final AbstractCompiler compiler) {
+          return new HotSwapCompilerPass() {
+            @Override
+            public void process(Node externs, Node root) {
+              checkNotNull(topScope);
+              checkNotNull(getTypedScopeCreator());
+
+              TypeCheck check = makeTypeCheck(compiler);
+              check.process(externs, root);
+              compiler.getErrorManager().setTypedPercent(check.getTypedPercent());
+            }
+
+            @Override
+            public void hotSwapScript(Node scriptRoot, Node originalRoot) {
+              makeTypeCheck(compiler).check(scriptRoot, false);
+            }
+          };
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return TYPE_CHECK_SUPPORTED;
+        }
+      };
+
+  /**
+   * Checks possible execution paths of the program for problems: missing return statements and dead
+   * code.
+   */
+  private final HotSwapPassFactory checkControlFlow =
+      new HotSwapPassFactory("checkControlFlow") {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          List<Callback> callbacks = new ArrayList<Callback>();
+          if (!options.disables(DiagnosticGroups.CHECK_USELESS_CODE)) {
+            callbacks.add(new CheckUnreachableCode(compiler));
+          }
+          if (!options.disables(DiagnosticGroups.MISSING_RETURN)) {
+            callbacks.add(new CheckMissingReturn(compiler));
+          }
+          return combineChecks(compiler, callbacks);
+        }
+
+        @Override
+        public FeatureSet featureSet() {
+          return ES2018;
+        }
+      };
+
+  /** Checks access controls. Depends on type-inference. */
+  /*
+  private final HotSwapPassFactory checkAccessControls =
+      new HotSwapPassFactory("checkAccessControls") {
+    @Override
+    protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+      return new CheckAccessControls(
+          compiler, options.enforceAccessControlCodingConventions);
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return TYPE_CHECK_SUPPORTED;
+    }
+  };*/
+
+  private final HotSwapPassFactory lintChecks =
+      new HotSwapPassFactory(PassNames.LINT_CHECKS) {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          ImmutableList.Builder<Callback> callbacks =
+              ImmutableList.<Callback>builder()
+                  .add(new CheckEmptyStatements(compiler))
+                  .add(new CheckEnums(compiler))
+                  .add(new CheckEs6ModuleFileStructure(compiler))
+                  .add(new CheckEs6Modules(compiler))
+                  .add(new CheckNoMutatedEs6Exports(compiler))
+                  .add(new CheckInterfaces(compiler))
+                  .add(new CheckJSDocStyle(compiler))
+                  .add(new CheckMissingSemicolon(compiler))
+                  .add(new CheckNullabilityModifiers(compiler))
+                  .add(new CheckPrimitiveAsObject(compiler))
+                  .add(new CheckPrototypeProperties(compiler))
+                  .add(new CheckUnusedLabels(compiler))
+                  .add(new CheckUselessBlocks(compiler));
+          return combineChecks(compiler, callbacks.build());
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  private final HotSwapPassFactory analyzerChecks =
+      new HotSwapPassFactory(PassNames.ANALYZER_CHECKS) {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          ImmutableList.Builder<Callback> callbacks = ImmutableList.builder();
+          if (options.enables(DiagnosticGroups.ANALYZER_CHECKS_INTERNAL)) {
+            callbacks
+                .add(new CheckNullableReturn(compiler))
+                .add(new CheckArrayWithGoogObject(compiler))
+                .add(new ImplicitNullabilityCheck(compiler));
+          }
+          // These are grouped together for better execution efficiency.
+          if (options.enables(DiagnosticGroups.UNUSED_PRIVATE_PROPERTY)) {
+            callbacks.add(new CheckUnusedPrivateProperties(compiler));
+          }
+          if (options.enables(DiagnosticGroups.MISSING_CONST_PROPERTY)) {
+            callbacks.add(new CheckConstPrivateProperties(compiler));
+          }
+          return combineChecks(compiler, callbacks.build());
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return TYPE_CHECK_SUPPORTED;
+        }
+      };
+
+  private final HotSwapPassFactory checkRequiresAndProvidesSorted =
+      new HotSwapPassFactory("checkRequiresAndProvidesSorted") {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new CheckRequiresAndProvidesSorted(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Executes the given callbacks with a {@link CombinedCompilerPass}. */
+  private static HotSwapCompilerPass combineChecks(AbstractCompiler compiler,
+      List<Callback> callbacks) {
+    checkArgument(!callbacks.isEmpty());
+    return new CombinedCompilerPass(compiler, callbacks);
+  }
+
+  /** A compiler pass that resolves types in the global scope. */
+  class GlobalTypeResolver implements HotSwapCompilerPass {
+    private final AbstractCompiler compiler;
+
+    GlobalTypeResolver(AbstractCompiler compiler) {
+      this.compiler = compiler;
+    }
+
+    @Override
+    public void process(Node externs, Node root) {
+      this.compiler.setTypeCheckingHasRun(true);
+      if (topScope == null) {
+        regenerateGlobalTypedScope(compiler, root.getParent());
+      } else {
+        compiler.getTypeRegistry().resolveTypes();
+      }
+    }
+    @Override
+    public void hotSwapScript(Node scriptRoot, Node originalRoot) {
+      patchGlobalTypedScope(compiler, scriptRoot);
+    }
+  }
+
+  /** A compiler pass that clears the global scope. */
+  class ClearTypedScope implements CompilerPass {
+    @Override
+    public void process(Node externs, Node root) {
+      clearTypedScope();
+    }
+  }
+
+  /** Checks global name usage. */
+  private final PassFactory checkGlobalNames =
+      new PassFactory("checkGlobalNames", true) {
+    @Override
+    protected CompilerPass create(final AbstractCompiler compiler) {
+      return new CompilerPass() {
+        @Override
+        public void process(Node externs, Node jsRoot) {
+          // Create a global namespace for analysis by check passes.
+          // Note that this class does all heavy computation lazily,
+          // so it's OK to create it here.
+          namespaceForChecks = new GlobalNamespace(compiler, externs, jsRoot);
+          new CheckGlobalNames(compiler, options.checkGlobalNamesLevel)
+              .injectNamespace(namespaceForChecks).process(externs, jsRoot);
+        }
+      };
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return TYPE_CHECK_SUPPORTED;
+    }
+  };
+
+  /** Checks that the code is ES5 strict compliant. */
+  private final PassFactory checkStrictMode =
+      new PassFactory("checkStrictMode", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new StrictModeCheck(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Process goog.tweak.getTweak() calls. */
+  private final PassFactory processTweaks = new PassFactory("processTweaks", true) {
+    @Override
+    protected CompilerPass create(final AbstractCompiler compiler) {
+      return new CompilerPass() {
+        @Override
+        public void process(Node externs, Node jsRoot) {
+          new ProcessTweaks(compiler,
+              options.getTweakProcessing().shouldStrip(),
+              options.getTweakReplacements()).process(externs, jsRoot);
+        }
+      };
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return TYPE_CHECK_SUPPORTED;
+    }
+  };
+
+  /** Override @define-annotated constants. */
+  private final PassFactory processDefines =
+      new PassFactory("processDefines", true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          return new CompilerPass() {
+            @Override
+            public void process(Node externs, Node jsRoot) {
+              HashMap<String, Node> replacements = new HashMap<String, Node>();
+              replacements.putAll(compiler.getDefaultDefineValues());
+              replacements.putAll(getAdditionalReplacements(options));
+              replacements.putAll(options.getDefineReplacements());
+              new ProcessDefines(compiler, ImmutableMap.copyOf(replacements), !options.checksOnly)
+                  .injectNamespace(namespaceForChecks)
+                  .process(externs, jsRoot);
+            }
+          };
+        }
+
+        @Override
+        public FeatureSet featureSet() {
+          return TYPE_CHECK_SUPPORTED;
+        }
+      };
+
+  /**
+   * Strips code for smaller compiled code. This is useful for removing debug
+   * statements to prevent leaking them publicly.
+   */
+  private final PassFactory stripCode = new PassFactory("stripCode", true) {
+    @Override
+    protected CompilerPass create(final AbstractCompiler compiler) {
+      return new CompilerPass() {
+        @Override
+        public void process(Node externs, Node jsRoot) {
+          CompilerOptions options = compiler.getOptions();
+          StripCode pass = new StripCode(compiler, options.stripTypes, options.stripNameSuffixes,
+              options.stripTypePrefixes, options.stripNamePrefixes);
+          if (options.getTweakProcessing().shouldStrip()) {
+            pass.enableTweakStripping();
+          }
+          pass.process(externs, jsRoot);
+        }
+      };
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return ES8_MODULES;
+    }
+  };
+
+  /** Release references to data that is only needed during checks. */
+  final PassFactory garbageCollectChecks =
+      new HotSwapPassFactory("garbageCollectChecks") {
+    @Override
+    protected HotSwapCompilerPass create(final AbstractCompiler compiler) {
+      return new HotSwapCompilerPass() {
+        @Override
+        public void process(Node externs, Node jsRoot) {
+          // Kill the global namespace so that it can be garbage collected
+          // after all passes are through with it.
+          namespaceForChecks = null;
+        }
+
+        @Override
+        public void hotSwapScript(Node scriptRoot, Node originalRoot) {
+          process(null, null);
+        }
+      };
+    }
+
+    @Override
+    public FeatureSet featureSet() {
+      return FeatureSet.latest();
+    }
+  };
+
+  /** Checks that all constants are not modified */
+  /*
+  private final PassFactory checkConsts =
+      new PassFactory("checkConsts", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new ConstCheck(compiler);
+        }
+
+        @Override
+        public FeatureSet featureSet() {
+          return ES2018;
+        }
+      };*/
+
+  /** Checks that the arguments are constants */
+  private final PassFactory checkConstParams =
+      new PassFactory(PassNames.CHECK_CONST_PARAMS, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new ConstParamCheck(compiler);
+        }
+
+        @Override
+        public FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Computes the names of functions for later analysis. */
+  private final PassFactory computeFunctionNames =
+      new PassFactory("computeFunctionNames", true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          return new CompilerPass() {
+            @Override
+            public void process(Node externs, Node root) {
+              CollectFunctionNames pass = new CollectFunctionNames(compiler);
+              pass.process(externs, root);
+              compiler.setFunctionNames(pass.getFunctionNames());
+            }
+          };
+        }
+
+        @Override
+        public FeatureSet featureSet() {
+          return ES2018;
+        }
+      };
+
+  /** Inserts run-time type assertions for debugging. */
+  private final PassFactory runtimeTypeCheck =
+      new PassFactory(PassNames.RUNTIME_TYPE_CHECK, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new RuntimeTypeCheck(compiler, options.runtimeTypeCheckLogFunction);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES5;
+        }
+      };
+
+  /** Generates unique ids. */
+  private final PassFactory replaceIdGenerators =
+      new PassFactory(PassNames.REPLACE_ID_GENERATORS, true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          return new CompilerPass() {
+            @Override
+            public void process(Node externs, Node root) {
+              ReplaceIdGenerators pass =
+                  new ReplaceIdGenerators(
+                      compiler,
+                      options.idGenerators,
+                      options.generatePseudoNames,
+                      options.idGeneratorsMapSerialized,
+                      options.xidHashFunction);
+              pass.process(externs, root);
+              compiler.setIdGeneratorMap(pass.getSerializedIdMappings());
+            }
+          };
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Replace strings. */
+  private final PassFactory replaceStrings =
+      new PassFactory("replaceStrings", true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          return new CompilerPass() {
+            @Override
+            public void process(Node externs, Node root) {
+              ReplaceStrings pass =
+                  new ReplaceStrings(
+                      compiler,
+                      options.replaceStringsPlaceholderToken,
+                      options.replaceStringsFunctionDescriptions,
+                      options.replaceStringsReservedStrings,
+                      options.replaceStringsInputMap);
+              pass.process(externs, root);
+              compiler.setStringMap(pass.getStringMap());
+            }
+          };
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Optimizes the "arguments" array. */
+  private final PassFactory optimizeArgumentsArray =
+      new PassFactory(PassNames.OPTIMIZE_ARGUMENTS_ARRAY, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new OptimizeArgumentsArray(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Remove variables set to goog.abstractMethod. */
+  private final PassFactory closureCodeRemoval =
+      new PassFactory("closureCodeRemoval", true) {
+    @Override
+    protected CompilerPass create(final AbstractCompiler compiler) {
+      return new ClosureCodeRemoval(compiler, options.removeAbstractMethods,
+          options.removeClosureAsserts);
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return ES8_MODULES;
+    }
+  };
+
+  /** Special case optimizations for closure functions. */
+  private final PassFactory closureOptimizePrimitives =
+      new PassFactory("closureOptimizePrimitives", true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          return new ClosureOptimizePrimitives(
+              compiler,
+              compiler.getOptions().propertyRenaming == PropertyRenamingPolicy.ALL_UNQUOTED,
+              compiler.getOptions().getOutputFeatureSet().contains(ES6));
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Puts global symbols into a single object. */
+  private final PassFactory rescopeGlobalSymbols =
+      new PassFactory("rescopeGlobalSymbols", true) {
+    @Override
+    protected CompilerPass create(AbstractCompiler compiler) {
+      return new RescopeGlobalSymbols(
+          compiler,
+          options.renamePrefixNamespace,
+          options.renamePrefixNamespaceAssumeCrossChunkNames);
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return ES8_MODULES;
+    }
+  };
+
+  /** Collapses names in the global scope. */
+  private final PassFactory collapseProperties =
+      new PassFactory(PassNames.COLLAPSE_PROPERTIES, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new CollapsePropertiesWithModuleSupport(compiler, options.getPropertyCollapseLevel(), sourceFileName, varRenameMapFile);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Rewrite properties as variables. */
+  private final PassFactory collapseObjectLiterals =
+      new PassFactory(PassNames.COLLAPSE_OBJECT_LITERALS, false) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new InlineObjectLiterals(compiler, compiler.getUniqueNameIdSupplier());
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Disambiguate property names based on the coding convention. */
+  private final PassFactory disambiguatePrivateProperties =
+      new PassFactory(PassNames.DISAMBIGUATE_PRIVATE_PROPERTIES, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new DisambiguatePrivateProperties(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Disambiguate property names based on type information. */
+  private final PassFactory disambiguateProperties =
+      new PassFactory(PassNames.DISAMBIGUATE_PROPERTIES, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new DisambiguateProperties(compiler, options.propertyInvalidationErrors);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Rewrite instance methods as static methods, to make them easier to inline. */
+  private final PassFactory devirtualizePrototypeMethods =
+      new PassFactory(PassNames.DEVIRTUALIZE_PROTOTYPE_METHODS, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          OptimizeCalls passes = new OptimizeCalls(compiler);
+          passes.addPass(new DevirtualizePrototypeMethods(compiler));
+          return passes;
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES5;
+        }
+      };
+
+  /**
+   * Optimizes unused function arguments, unused return values, and inlines constant parameters.
+   * Also runs RemoveUnusedCode.
+   */
+  private final PassFactory optimizeCalls =
+      new PassFactory(PassNames.OPTIMIZE_CALLS, false) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          OptimizeCalls passes = new OptimizeCalls(compiler);
+          // Remove unused return values.
+          passes.addPass(new OptimizeReturns(compiler));
+          // Remove all parameters that are constants or unused.
+          passes.addPass(new OptimizeParameters(compiler));
+          return passes;
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /**
+   * Look for function calls that are pure, and annotate them
+   * that way.
+   */
+  private final PassFactory markPureFunctions =
+      new PassFactory("markPureFunctions", true) {
+    @Override
+    protected CompilerPass create(AbstractCompiler compiler) {
+      return new PureFunctionIdentifier.Driver(
+          compiler, options.debugFunctionSideEffectsPath);
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return ES8_MODULES;
+    }
+  };
+
+  /** Look for function calls that have no side effects, and annotate them that way. */
+  private final PassFactory markNoSideEffectCalls =
+      new PassFactory(PassNames.MARK_NO_SIDE_EFFECT_CALLS, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new MarkNoSideEffectCalls(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES5;
+        }
+      };
+
+  /** Inlines variables heuristically. */
+  private final PassFactory inlineVariables =
+      new PassFactory(PassNames.INLINE_VARIABLES, false) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          InlineVariables.Mode mode;
+          if (options.inlineVariables) {
+            mode = InlineVariables.Mode.ALL;
+          } else if (options.inlineLocalVariables) {
+            mode = InlineVariables.Mode.LOCALS_ONLY;
+          } else {
+            throw new IllegalStateException("No variable inlining option set.");
+          }
+          return new InlineVariables(compiler, mode, true);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Inlines variables that are marked as constants. */
+  private final PassFactory inlineConstants =
+      new PassFactory("inlineConstants", false) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new InlineVariables(compiler, InlineVariables.Mode.CONSTANTS_ONLY, true);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Use data flow analysis to remove dead branches. */
+  private final PassFactory removeUnreachableCode =
+      new PassFactory(PassNames.REMOVE_UNREACHABLE_CODE, false) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new UnreachableCodeElimination(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8;
+        }
+      };
+
+  /**
+   * Use data flow analysis to remove dead branches.
+   */
+  private final PassFactory removeUnusedPolyfills =
+      new PassFactory("removeUnusedPolyfills", true) {
+    @Override
+    protected CompilerPass create(AbstractCompiler compiler) {
+      return new RemoveUnusedPolyfills(compiler);
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return ES8_MODULES;
+    }
+  };
+
+  /** Inlines simple methods, like getters */
+  private final PassFactory inlineSimpleMethods =
+      new PassFactory("inlineSimpleMethods", false) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new InlineSimpleMethods(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Kills dead assignments. */
+  private final PassFactory deadAssignmentsElimination =
+      new PassFactory(PassNames.DEAD_ASSIGNMENT_ELIMINATION, false) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new DeadAssignmentsElimination(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Kills dead property assignments. */
+  private final PassFactory deadPropertyAssignmentElimination =
+      new PassFactory("deadPropertyAssignmentElimination", false) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new DeadPropertyAssignmentElimination(compiler);
+        }
+
+        @Override
+        public FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Inlines function calls. */
+  private final PassFactory inlineFunctions =
+      new PassFactory(PassNames.INLINE_FUNCTIONS, false) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new InlineFunctions(
+              compiler,
+              compiler.getUniqueNameIdSupplier(),
+              options.getInlineFunctionsLevel(),
+              options.assumeStrictThis() || options.expectStrictModeInput(),
+              options.assumeClosuresOnlyCaptureReferences,
+              options.maxFunctionSizeAfterInlining);
+        }
+
+        @Override
+        public FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Inlines constant properties. */
+  private final PassFactory inlineProperties =
+      new PassFactory(PassNames.INLINE_PROPERTIES, false) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new InlineProperties(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES5;
+        }
+      };
+
+  private final PassFactory removeUnusedCodeOnce = getRemoveUnusedCode(true /* isOneTimePass */);
+  private final PassFactory removeUnusedCode = getRemoveUnusedCode(false /* isOneTimePass */);
+
+  private PassFactory getRemoveUnusedCode(boolean isOneTimePass) {
+    /** Removes variables that are never used. */
+    return new PassFactory(PassNames.REMOVE_UNUSED_CODE, isOneTimePass) {
+      @Override
+      protected CompilerPass create(AbstractCompiler compiler) {
+        boolean preserveAnonymousFunctionNames =
+            options.anonymousFunctionNaming != AnonymousFunctionNamingPolicy.OFF;
+        return new RemoveUnusedCode.Builder(compiler)
+            .removeLocalVars(options.removeUnusedLocalVars)
+            .removeGlobals(options.removeUnusedVars)
+            .preserveFunctionExpressionNames(preserveAnonymousFunctionNames)
+            .removeUnusedPrototypeProperties(options.removeUnusedPrototypeProperties)
+            .allowRemovalOfExternProperties(options.removeUnusedPrototypePropertiesInExterns)
+            .removeUnusedThisProperties(options.isRemoveUnusedClassProperties())
+            .removeUnusedObjectDefinePropertiesDefinitions(options.isRemoveUnusedClassProperties())
+            .removeUnusedConstructorProperties(options.isRemoveUnusedConstructorProperties())
+            .build();
+      }
+
+      @Override
+      public FeatureSet featureSet() {
+        return ES8_MODULES;
+      }
+    };
+
+  }
+
+  /** Move global symbols to a deeper common module */
+  private final PassFactory crossModuleCodeMotion =
+      new PassFactory(PassNames.CROSS_CHUNK_CODE_MOTION, false) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new CrossChunkCodeMotion(
+              compiler,
+              compiler.getModuleGraph(),
+              options.parentChunkCanSeeSymbolsDeclaredInChildren);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Move methods to a deeper common module */
+  private final PassFactory crossModuleMethodMotion =
+      new PassFactory(PassNames.CROSS_CHUNK_METHOD_MOTION, false) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new CrossChunkMethodMotion(
+              compiler,
+              compiler.getCrossModuleIdGenerator(),
+              // Only move properties in externs if we're not treating
+              // them as exports.
+              options.removeUnusedPrototypePropertiesInExterns,
+              options.crossChunkCodeMotionNoStubMethods);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** A data-flow based variable inliner. */
+  private final PassFactory flowSensitiveInlineVariables =
+      new PassFactory(PassNames.FLOW_SENSITIVE_INLINE_VARIABLES, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new FlowSensitiveInlineVariables(compiler);
+        }
+
+        @Override
+        public FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Uses register-allocation algorithms to use fewer variables. */
+  private final PassFactory coalesceVariableNames =
+      new PassFactory(PassNames.COALESCE_VARIABLE_NAMES, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new CoalesceVariableNames(compiler, options.generatePseudoNames);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Some simple, local collapses (e.g., {@code var x; var y;} becomes {@code var x,y;}. */
+  private final PassFactory exploitAssign =
+      new PassFactory(PassNames.EXPLOIT_ASSIGN, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new PeepholeOptimizationsPass(compiler, getName(), new ExploitAssigns());
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Some simple, local collapses (e.g., {@code var x; var y;} becomes {@code var x,y;}. */
+  private final PassFactory collapseVariableDeclarations =
+      new PassFactory(PassNames.COLLAPSE_VARIABLE_DECLARATIONS, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new CollapseVariableDeclarations(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Extracts common sub-expressions. */
+  private final PassFactory extractPrototypeMemberDeclarations =
+      new PassFactory(PassNames.EXTRACT_PROTOTYPE_MEMBER_DECLARATIONS, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          Pattern pattern;
+          switch (options.extractPrototypeMemberDeclarations) {
+            case USE_GLOBAL_TEMP:
+              pattern = Pattern.USE_GLOBAL_TEMP;
+              break;
+            case USE_IIFE:
+              pattern = Pattern.USE_IIFE;
+              break;
+            default:
+              throw new IllegalStateException("unexpected");
+          }
+
+          return new ExtractPrototypeMemberDeclarations(compiler, pattern);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8;
+        }
+      };
+
+  /** Rewrites common function definitions to be more compact. */
+  private final PassFactory rewriteFunctionExpressions =
+      new PassFactory(PassNames.REWRITE_FUNCTION_EXPRESSIONS, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new FunctionRewriter(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return FeatureSet.latest();
+        }
+      };
+
+  /** Collapses functions to not use the VAR keyword. */
+  private final PassFactory collapseAnonymousFunctions =
+      new PassFactory(PassNames.COLLAPSE_ANONYMOUS_FUNCTIONS, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new CollapseAnonymousFunctions(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Moves function declarations to the top, to simulate actual hoisting. */
+  private final PassFactory moveFunctionDeclarations =
+      new PassFactory(PassNames.MOVE_FUNCTION_DECLARATIONS, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new MoveFunctionDeclarations(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8;
+        }
+      };
+
+  private final PassFactory nameUnmappedAnonymousFunctions =
+      new PassFactory(PassNames.NAME_ANONYMOUS_FUNCTIONS, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new NameAnonymousFunctions(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  private final PassFactory nameMappedAnonymousFunctions =
+      new PassFactory(PassNames.NAME_ANONYMOUS_FUNCTIONS, true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          return new CompilerPass() {
+            @Override
+            public void process(Node externs, Node root) {
+              NameAnonymousFunctionsMapped naf =
+                  new NameAnonymousFunctionsMapped(
+                      compiler, options.inputAnonymousFunctionNamingMap);
+              naf.process(externs, root);
+              compiler.setAnonymousFunctionNameMap(naf.getFunctionMap());
+            }
+          };
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /**
+   * Alias string literals with global variables, to avoid creating lots of
+   * transient objects.
+   */
+  private final PassFactory aliasStrings = new PassFactory("aliasStrings", true) {
+    @Override
+    protected CompilerPass create(AbstractCompiler compiler) {
+      return new AliasStrings(
+          compiler,
+          compiler.getModuleGraph(),
+          options.aliasAllStrings ? null : options.aliasableStrings,
+          options.aliasStringsBlacklist,
+          options.outputJsStringUsage);
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return ES8_MODULES;
+    }
+  };
+
+  /** Handling for the ObjectPropertyString primitive. */
+  private final PassFactory objectPropertyStringPostprocess =
+      new PassFactory("ObjectPropertyStringPostprocess", true) {
+    @Override
+    protected CompilerPass create(AbstractCompiler compiler) {
+      return new ObjectPropertyStringPostprocess(compiler);
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return ES5;
+    }
+  };
+
+  /**
+   * Renames properties so that the two properties that never appear on the same object get the same
+   * name.
+   */
+  private final PassFactory ambiguateProperties =
+      new PassFactory(PassNames.AMBIGUATE_PROPERTIES, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new AmbiguateProperties(
+              compiler,
+              options.getPropertyReservedNamingFirstChars(),
+              options.getPropertyReservedNamingNonFirstChars());
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Mark the point at which the normalized AST assumptions no longer hold. */
+  private final PassFactory markUnnormalized =
+      new PassFactory("markUnnormalized", true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          return new CompilerPass() {
+            @Override
+            public void process(Node externs, Node root) {
+              compiler.setLifeCycleStage(LifeCycleStage.RAW);
+            }
+          };
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return FeatureSet.latest();
+        }
+      };
+
+  private final PassFactory normalize =
+      new PassFactory(PassNames.NORMALIZE, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new Normalize(compiler, false);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          // TODO(johnlenz): Update this and gatherRawExports to latest()
+          return ES8_MODULES;
+        }
+      };
+
+  private final PassFactory externExports =
+      new PassFactory(PassNames.EXTERN_EXPORTS, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new ExternExportsPass(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES5;
+        }
+      };
+
+  /** Denormalize the AST for code generation. */
+  private final PassFactory denormalize = new PassFactory("denormalize", true) {
+    @Override
+    protected CompilerPass create(AbstractCompiler compiler) {
+      return new Denormalize(compiler);
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return ES8_MODULES;
+    }
+  };
+
+  /** Inverting name normalization. */
+  private final PassFactory invertContextualRenaming =
+      new PassFactory("invertContextualRenaming", true) {
+    @Override
+    protected CompilerPass create(AbstractCompiler compiler) {
+      return MakeDeclaredNamesUnique.getContextualRenameInverter(compiler);
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return ES8_MODULES;
+    }
+  };
+
+  /** Renames properties. */
+  private final PassFactory renameProperties =
+      new PassFactory("renameProperties", true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          checkState(options.propertyRenaming == PropertyRenamingPolicy.ALL_UNQUOTED);
+          final VariableMap prevPropertyMap = options.inputPropertyMap;
+          return new CompilerPass() {
+            @Override
+            public void process(Node externs, Node root) {
+              RenamePropertiesWithModuleSupport rprop =
+                  new RenamePropertiesWithModuleSupport(
+                      compiler,
+                      options.generatePseudoNames,
+                      prevPropertyMap,
+                      options.getPropertyReservedNamingFirstChars(),
+                      options.getPropertyReservedNamingNonFirstChars(),
+                      options.nameGenerator);
+              rprop.process(externs, root);
+              compiler.setPropertyMap(rprop.getPropertyMap());
+            }
+          };
+        }
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Renames variables. */
+  private final PassFactory renameVars = new PassFactory("renameVars", true) {
+    @Override
+    protected CompilerPass create(final AbstractCompiler compiler) {
+      final VariableMap prevVariableMap = options.inputVariableMap;
+      return new CompilerPass() {
+        @Override public void process(Node externs, Node root) {
+          compiler.setVariableMap(runVariableRenaming(
+              compiler, prevVariableMap, externs, root));
+        }
+      };
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return ES8_MODULES;
+    }
+  };
+
+  private VariableMap runVariableRenaming(
+      AbstractCompiler compiler, VariableMap prevVariableMap,
+      Node externs, Node root) {
+    char[] reservedChars =
+        options.anonymousFunctionNaming.getReservedCharacters();
+    boolean preserveAnonymousFunctionNames =
+        options.anonymousFunctionNaming != AnonymousFunctionNamingPolicy.OFF;
+    Set<String> reservedNames = new HashSet<String>();
+    if (options.renamePrefixNamespace != null) {
+      // don't use the prefix name as a global symbol.
+      reservedNames.add(options.renamePrefixNamespace);
+    }
+    reservedNames.addAll(compiler.getExportedNames());
+    reservedNames.addAll(ParserRunner.getReservedVars());
+    RenameVarsWithModuleSupport rn = new RenameVarsWithModuleSupport(
+        compiler,
+        options.renamePrefix,
+        options.variableRenaming == VariableRenamingPolicy.LOCAL,
+        preserveAnonymousFunctionNames,
+        options.generatePseudoNames,
+        options.shadowVariables,
+        options.preferStableNames,
+        prevVariableMap,
+        reservedChars,
+        reservedNames,
+        options.nameGenerator);
+    rn.process(externs, root);
+    return rn.getVariableMap();
+  }
+
+  /** Renames labels */
+  private final PassFactory renameLabels =
+      new PassFactory("renameLabels", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new RenameLabels(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Convert bracket access to dot access */
+  private final PassFactory convertToDottedProperties =
+      new PassFactory(PassNames.CONVERT_TO_DOTTED_PROPERTIES, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new ConvertToDottedProperties(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  private final PassFactory checkAstValidity =
+      new PassFactory("checkAstValidity", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new AstValidator(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return FeatureSet.latest();
+        }
+      };
+
+  /** Checks that all variables are defined. */
+  private final PassFactory varCheckValidity =
+      new PassFactory("varCheckValidity", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new VarCheck(compiler, true);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Adds instrumentations according to an instrumentation template. */
+  private final PassFactory instrumentFunctions =
+      new PassFactory("instrumentFunctions", true) {
+    @Override
+    protected CompilerPass create(final AbstractCompiler compiler) {
+      return new InstrumentFunctions(
+          compiler, compiler.getFunctionNames(),
+          options.instrumentationTemplate, options.appNameStr);
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return ES5;
+    }
+  };
+
+  private final PassFactory instrumentForCodeCoverage =
+      new PassFactory("instrumentForCodeCoverage", true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          // TODO(johnlenz): make global instrumentation an option
+          if (options.instrumentBranchCoverage) {
+            return new CoverageInstrumentationPass(
+                compiler, CoverageReach.CONDITIONAL, InstrumentOption.BRANCH_ONLY);
+          } else {
+            return new CoverageInstrumentationPass(compiler, CoverageReach.CONDITIONAL);
+          }
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES5;
+        }
+      };
+
+  /** Extern property names gathering pass. */
+  private final PassFactory gatherExternProperties =
+      new PassFactory("gatherExternProperties", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new GatherExternProperties(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+     };
+
+  /**
+   * Runs custom passes that are designated to run at a particular time.
+   */
+  private PassFactory getCustomPasses(
+      final CustomPassExecutionTime executionTime) {
+    return new PassFactory("runCustomPasses", true) {
+      @Override
+      protected CompilerPass create(final AbstractCompiler compiler) {
+        return runInSerial(options.customPasses.get(executionTime));
+      }
+
+      @Override
+      protected FeatureSet featureSet() {
+        return ES5;
+      }
+    };
+  }
+
+  /** Create a compiler pass that runs the given passes in serial. */
+  private static CompilerPass runInSerial(
+      final Collection<CompilerPass> passes) {
+    return new CompilerPass() {
+      @Override public void process(Node externs, Node root) {
+        for (CompilerPass pass : passes) {
+          pass.process(externs, root);
+        }
+      }
+    };
+  }
+
+  @VisibleForTesting
+  static Map<String, Node> getAdditionalReplacements(CompilerOptions options) {
+    Map<String, Node> additionalReplacements = new HashMap<String, Node>();
+
+    if (options.markAsCompiled || options.closurePass) {
+      additionalReplacements.put(COMPILED_CONSTANT_NAME, IR.trueNode());
+    }
+
+    if (options.closurePass && options.locale != null) {
+      additionalReplacements.put(CLOSURE_LOCALE_CONSTANT_NAME,
+          IR.string(options.locale));
+    }
+
+    return additionalReplacements;
+  }
+
+  /** Rewrites Polymer({}) */
+  private final HotSwapPassFactory polymerPass =
+      new HotSwapPassFactory("polymerPass") {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new PolymerPass(
+              compiler,
+              compiler.getOptions().polymerVersion,
+              compiler.getOptions().polymerExportPolicy,
+              compiler.getOptions().propertyRenaming == PropertyRenamingPolicy.ALL_UNQUOTED);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  private final PassFactory chromePass = new PassFactory("chromePass", true) {
+    @Override
+    protected CompilerPass create(AbstractCompiler compiler) {
+      return new ChromePass(compiler);
+    }
+
+    @Override
+    protected FeatureSet featureSet() {
+      return ES8_MODULES;
+    }
+  };
+
+  /** Rewrites the super accessors calls to support Dart Dev Compiler output. */
+  private final HotSwapPassFactory dartSuperAccessorsPass =
+      new HotSwapPassFactory("dartSuperAccessorsPass") {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new DartSuperAccessorsPass(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  /** Rewrites J2CL constructs to be more optimizable. */
+  private final PassFactory j2clConstantHoisterPass =
+      new PassFactory("j2clConstantHoisterPass", false) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new J2clConstantHoisterPass(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Optimizes J2CL clinit methods. */
+  private final PassFactory j2clClinitPass =
+      new PassFactory("j2clClinitPass", false) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          List<Node> changedScopeNodes = compiler.getChangedScopeNodesForPass(getName());
+          return new J2clClinitPrunerPass(compiler, changedScopeNodes);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Rewrites J2CL constructs to be more optimizable. */
+  private final PassFactory j2clPropertyInlinerPass =
+      new PassFactory("j2clES6Pass", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new J2clPropertyInlinerPass(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Rewrites J2CL constructs to be more optimizable. */
+  private final PassFactory j2clPass =
+      new PassFactory("j2clPass", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new J2clPass(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Rewrites J2CL constructs to be more optimizable. */
+  private final PassFactory j2clUtilGetDefineRewriterPass =
+      new PassFactory("j2clUtilGetDefineRewriterPass", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new J2clUtilGetDefineRewriterPass(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  private final PassFactory j2clAssertRemovalPass =
+      new PassFactory("j2clAssertRemovalPass", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new J2clAssertRemovalPass(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  private final PassFactory j2clSourceFileChecker =
+      new PassFactory("j2clSourceFileChecker", true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          return new J2clSourceFileChecker(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return FeatureSet.latest();
+        }
+      };
+
+  private final PassFactory j2clChecksPass =
+      new PassFactory("j2clChecksPass", true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          return new J2clChecksPass(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES2018;
+        }
+      };
+
+  private final PassFactory checkConformance =
+      new PassFactory("checkConformance", true) {
+        @Override
+        protected CompilerPass create(final AbstractCompiler compiler) {
+          return new CheckConformance(
+              compiler, ImmutableList.copyOf(options.getConformanceConfigs()));
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return TYPE_CHECK_SUPPORTED;
+        }
+      };
+
+  /** Optimizations that output ES6 features. */
+  private final PassFactory optimizeToEs6 =
+      new PassFactory("optimizeToEs6", true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new SubstituteEs6Syntax(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  /** Rewrites goog.module in whitespace only mode */
+  private final HotSwapPassFactory whitespaceWrapGoogModules =
+      new HotSwapPassFactory("whitespaceWrapGoogModules") {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new WhitespaceWrapGoogModules(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES8_MODULES;
+        }
+      };
+
+  private final PassFactory rewriteCommonJsModules =
+      new PassFactory(PassNames.REWRITE_COMMON_JS_MODULES, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new ProcessCommonJSModules(compiler);
+        }
+
+        @Override
+        public FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  private final PassFactory rewriteScriptsToEs6Modules =
+      new PassFactory(PassNames.REWRITE_SCRIPTS_TO_ES6_MODULES, true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new Es6RewriteScriptsToModules(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  private final HotSwapPassFactory gatherModuleMetadataPass =
+      new HotSwapPassFactory(PassNames.GATHER_MODULE_METADATA) {
+        @Override
+        protected HotSwapCompilerPass create(AbstractCompiler compiler) {
+          return new GatherModuleMetadata(
+              compiler, options.processCommonJSModules, options.moduleResolutionMode);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+
+  private final PassFactory gatherGettersAndSetters =
+      new PassFactory(PassNames.GATHER_GETTERS_AND_SETTERS, /* isOneTimePass= */ true) {
+        @Override
+        protected CompilerPass create(AbstractCompiler compiler) {
+          return new GatherGettersAndSetterProperties(compiler);
+        }
+
+        @Override
+        protected FeatureSet featureSet() {
+          return ES_NEXT;
+        }
+      };
+}
diff --git a/compiler-jx/src/main/java/com/google/javascript/jscomp/ShadowVariablesWithModuleSupport.java b/compiler-jx/src/main/java/com/google/javascript/jscomp/ShadowVariablesWithModuleSupport.java
new file mode 100644
index 0000000..83d74ed
--- /dev/null
+++ b/compiler-jx/src/main/java/com/google/javascript/jscomp/ShadowVariablesWithModuleSupport.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright 2011 The Closure Compiler Authors.
+ *
+ * Licensed 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 com.google.javascript.jscomp;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback;
+import com.google.javascript.jscomp.NodeTraversal.ScopedCallback;
+import com.google.javascript.jscomp.RenameVarsWithModuleSupport.Assignment;
+import com.google.javascript.rhino.Node;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.SortedSet;
+
+/**
+ * Apache Royale copied ShadowVariables and modified it to handle
+ * Royale modules.  The only change is to uses classes from
+ * RenameVarsWithModuleSupport instead of RenameVars.
+ * 
+ * Tries to compute a list of variables that can shadow a variable in the
+ * outer scope.
+ *
+ * For example:
+ *
+ * <code>
+ * var a = function() {
+ *   var b = getB();
+ *   b();
+ *   return function(y) {};
+ * };
+ * </code>
+ *
+ * Normally, b would be mapped to variable L0, y would be L1.
+ *
+ * Instead we are going to make y shadows L0 in hope of using less variables
+ * and reusing frequently used local names.
+ *
+ */
+class ShadowVariablesWithModuleSupport implements CompilerPass {
+
+  // Keep a map of Upward Referencing name nodes of each scope.
+  // A name is upward referencing name of a scope if:
+  //
+  // 1) It refers to (or defines) a name that is defined in the current
+  // scope or any scope above the current scope that isn't the
+  // global scope.
+  //
+  // 2) It is a upward referencing name of a child scope of this scope.
+  //
+  // Example:
+  // var x; var y; function foo(a) { function bar(b) { x, a } }
+  // The upward referencing names in scope 'foo' is bar, b, x and a;
+  // The key to this map is the root node of the scope.
+  //
+  // We can see that for any variable x in the current scope, we can shadow
+  // a variable y in an outer scope given that y is not a upward referencing
+  // name of the current scope.
+
+  // TODO(user): Maps scope to string instead of Node to string.
+  // Make sure of scope memorization to minimize scope creation cost.
+  private final Multimap<Node, String> scopeUpRefMap = HashMultimap.create();
+
+  // Maps each local variable to all of its referencing NAME nodes in any scope.
+  private final Multimap<Var, Reference> varToNameUsage = HashMultimap.create();
+
+  private final AbstractCompiler compiler;
+
+  // All the information used for renaming.
+  private final SortedSet<Assignment> varsByFrequency;
+  private final Map<String, Assignment> assignments;
+  private final Map<Node, String> oldPseudoNameMap;
+  private final Map<Node, String> deltaPseudoNameMap;
+
+
+  /**
+   * @param assignments Map of old variable names to its assignment Objects.
+   * @param varsByFrequency Sorted variable assignments by Frequency.
+   * @param pseudoNameMap The current pseudo name map so this pass can update
+   *     it accordingly.
+   */
+  ShadowVariablesWithModuleSupport(
+      AbstractCompiler compiler,
+      Map<String, Assignment> assignments,
+      SortedSet<Assignment> varsByFrequency,
+      Map<Node, String> pseudoNameMap) {
+    this.compiler = compiler;
+    this.assignments = assignments;
+    this.varsByFrequency = varsByFrequency;
+    this.oldPseudoNameMap = pseudoNameMap;
+    this.deltaPseudoNameMap = new LinkedHashMap<Node, String>();
+  }
+
+  @Override
+  public void process(Node externs, Node root) {
+    // The algorithm is divided into two stages:
+    //
+    // 1. Information gathering (variable usage, upward referencing)
+    //
+    // 2. Tries to find shadows for each variables, updates the
+    //    variable usage frequency map.
+    //
+    // 3. Updates the pseudo naming map if needed.
+    NodeTraversal.traverse(compiler, root, new GatherReferenceInfo());
+    NodeTraversal.traverse(compiler, root, new DoShadowVariables());
+
+    if (oldPseudoNameMap != null) {
+      oldPseudoNameMap.putAll(deltaPseudoNameMap);
+    }
+  }
+
+  private class GatherReferenceInfo extends AbstractPostOrderCallback {
+    @Override
+    public void visit(NodeTraversal t, Node n, Node parent) {
+      // Skipping over non-name nodes and empty function names.
+      if (!NodeUtil.isReferenceName(n)) {
+        return;
+      }
+
+      // We focus on shadowing local variables as their name occurs much more
+      // than global names.
+      // TODO(user): Alternatively, we could experiment with using a local
+      // name to shadow a global variable.
+      if (t.inGlobalScope()) {
+        return;
+      }
+
+      Scope scope = t.getScope();
+      Var var = scope.getVar(n.getString());
+      if (var == null) {
+        // extern name or undefined name.
+        return;
+      }
+
+      if (var.getScope().isGlobal()) {
+        // We will not shadow a global variable name.
+        return;
+      }
+
+      // Using the definition of upward referencing, fill in the map.
+      if (var.getScope() != scope) {
+        for (Scope s = scope; s != var.getScope() && s.isLocal(); s = s.getParent()) {
+          scopeUpRefMap.put(s.getRootNode(), var.name);
+        }
+      } else {
+        scopeUpRefMap.put(t.getScopeRoot(), var.name);
+      }
+
+      // Make sure that we don't shadow function parameters or function names from a function block
+      // scope, eg.:
+      // function f(a) { ... var a; ... } // Unsafe
+      if (scope.isFunctionScope() && var.getScope() == scope) {
+        scopeUpRefMap.put(scope.getRootNode().getLastChild(), var.name);
+      }
+
+      // Find in the usage map that tracks a var and all of its usage.
+      varToNameUsage.put(var, new Reference(n, scope));
+    }
+  }
+
+  private class DoShadowVariables extends AbstractPostOrderCallback
+      implements ScopedCallback {
+
+    @Override
+    public void enterScope(NodeTraversal t) {
+      if (t.inGlobalScope()) {
+        return;
+      }
+
+      // Since we don't shadow global, there is nothing to be done in the
+      // first immediate local scope as well.
+      Node scopeRoot = t.getScopeRoot();
+      if ((scopeRoot.isFunction()
+              && NodeUtil.getEnclosingFunction(scopeRoot.getParent()) == null)
+          || (NodeUtil.isFunctionBlock(scopeRoot)
+              && NodeUtil.getEnclosingFunction(scopeRoot.getGrandparent()) == null)) {
+        return;
+      }
+
+      Scope s = t.getScope();
+      for (Var var : s.getVarIterable()) {
+        // Don't shadow variables that are bleed-out functions or caught exceptions to workaround
+        // IE8 bugs.
+        // TODO(moz): Gate this behind languageMode=ES3.
+        if (var.isBleedingFunction() || var.isCatch()) {
+          continue;
+        }
+
+        // Don't shadow an exported local.
+        if (compiler.getCodingConvention().isExported(var.name, s.isLocal())) {
+          continue;
+        }
+
+        // The name assignment being shadowed.
+        Assignment localAssignment = assignments.get(var.getName());
+        if (localAssignment == null) {
+          continue;
+        }
+        // Try to run this check last as it is more expensive than the above checks.
+
+        // Try to look for the best shadow for the current candidate.
+        Assignment bestShadow = findBestShadow(s, var);
+        if (bestShadow == null) {
+          continue;
+        }
+
+        // Only shadow if this increases the number of occurrences of the
+        // shadowed variable.
+        if (bestShadow.count < localAssignment.count) {
+          continue; // Hope the next local variable would have a smaller count.
+        }
+
+        doShadow(localAssignment, bestShadow, var);
+
+        if (oldPseudoNameMap != null) {
+          String targetPseudoName =
+            oldPseudoNameMap.get(s.getVar(bestShadow.oldName).nameNode);
+          for (Reference use : varToNameUsage.get(var)) {
+            deltaPseudoNameMap.put(use.nameNode, targetPseudoName);
+          }
+        }
+      }
+    }
+
+    @Override
+    public void exitScope(NodeTraversal t) {}
+
+    @Override
+    public void visit(NodeTraversal t, Node n, Node parent) {}
+
+    /**
+     * @return An assignment that can be used as a shadow for a local variable
+     *     in the scope defined by curScopeRoot.
+     */
+    private Assignment findBestShadow(Scope curScope, Var var) {
+      // Search for the candidate starting from the most used local.
+      for (Assignment assignment : varsByFrequency) {
+        if (assignment.isLocal) {
+          if (!scopeUpRefMap.containsEntry(curScope.getRootNode(), assignment.oldName)) {
+            if (curScope.hasSlot(assignment.oldName)) {
+              // Don't shadow if the scopes are the same eg.:
+              // function f() { var a = 1; { var a = 2; } } // Unsafe
+              Var toShadow = curScope.getVar(assignment.oldName);
+              if (var.getScope() != toShadow.getScope()) {
+                return assignment;
+              }
+            }
+          }
+        }
+      }
+      return null;
+    }
+
+    private void doShadow(Assignment original, Assignment toShadow, Var var) {
+      Scope s = var.getScope();
+      // We are now shadowing 'bestShadow' with localAssignment.
+      // All of the reference NAME node of this variable.
+      Collection<Reference> references = varToNameUsage.get(var);
+
+      // First remove both assignments from the sorted list since they need
+      // to be re-sorted.
+      varsByFrequency.remove(original);
+      varsByFrequency.remove(toShadow);
+
+      // Adjust the count offset by the inner scope variable.
+      original.count -= references.size();
+      toShadow.count += references.size();
+
+      // Add it back to the sorted list after re-adjustment.
+      varsByFrequency.add(original);
+      varsByFrequency.add(toShadow);
+
+      // This is an important step. If variable L7 is going to be renamed to
+      // L1, by definition of upward referencing, The name L1 is now in the
+      // set of upward referencing names of the current scope up to the
+      // declaring scope of the best shadow variable.
+      Var shadowed = s.getVar(toShadow.oldName);
+      if (shadowed != null) {
+        if (s.isFunctionScope() && s.getRootNode().getLastChild().isBlock()) {
+          scopeUpRefMap.put(s.getRootNode().getLastChild(), toShadow.oldName);
+          scopeUpRefMap.remove(s.getRootNode().getLastChild(), original.oldName);
+        }
+        for (Scope curScope = s; curScope != shadowed.scope; curScope = curScope.getParent()) {
+          scopeUpRefMap.put(curScope.getRootNode(), toShadow.oldName);
+          scopeUpRefMap.remove(curScope.getRootNode(), original.oldName);
+        }
+      }
+
+      // Mark all the references as shadowed.
+      for (Reference ref : references) {
+        Node n = ref.nameNode;
+        n.setString(toShadow.oldName);
+        if (ref.scope.getRootNode() == s.getRootNode()) {
+          if (var.getNameNode() != ref.nameNode) {
+            scopeUpRefMap.put(s.getRootNode(), toShadow.oldName);
+            scopeUpRefMap.remove(s.getRootNode(), original.oldName);
+          }
+        } else {
+          for (Scope curScope = ref.scope;
+              curScope.getRootNode() != s.getRootNode();
+              curScope = curScope.getParent()) {
+            scopeUpRefMap.put(curScope.getRootNode(), toShadow.oldName);
+            scopeUpRefMap.remove(curScope.getRootNode(), original.oldName);
+          }
+        }
+      }
+    }
+  }
+
+  private static final class Reference {
+    private final Node nameNode;
+    private final Scope scope;
+
+    private Reference(Node nameNode, Scope scope) {
+      this.nameNode = nameNode;
+      this.scope = scope;
+    }
+  }
+}
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/asdoc/royale/ASDocComment.java b/compiler-jx/src/main/java/org/apache/royale/compiler/asdoc/royale/ASDocComment.java
index a1006dc..54c3af6 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/asdoc/royale/ASDocComment.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/asdoc/royale/ASDocComment.java
@@ -121,6 +121,9 @@
             		tagMap = new HashMap<String, List<IASDocTag>>();
             	
             	int after = line.indexOf(" ", at + 1);
+            	int tabAfter = line.indexOf("\t", at + 1);
+            	if (tabAfter != -1 && after != -1 && tabAfter < after)
+            		after = tabAfter;
             	if (after == -1)
             	{
             		tagMap.put(line.substring(at + 1), null);
@@ -134,7 +137,7 @@
             			tags = new ArrayList<IASDocTag>();
             			tagMap.put(tagName, tags);
             		}
-            		tags.add(new ASDocTag(tagName, line.substring(after + 1)));
+            		tags.add(new ASDocTag(tagName, line.substring(after + 1).trim()));
             	}            		
             }
         }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/ASDOCJSC.java b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/ASDOCJSC.java
index d8c4601..133cfa0 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/ASDOCJSC.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/ASDOCJSC.java
@@ -249,7 +249,10 @@
                         final File outputClassFile = getOutputClassFile(
                                 cu.getQualifiedNames().get(0), outputFolder);
 
-                        System.out.println("Compiling file: " + outputClassFile);
+                        if (config.isVerbose())
+                        {
+                            System.out.println("Compiling file: " + outputClassFile);
+                        }
 
                         ICompilationUnit unit = cu;
 
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSC.java b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSC.java
index f4201e2..23da56e 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSC.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSC.java
@@ -26,11 +26,14 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Enumeration;
 import java.util.List;
 import java.util.Set;
+import java.util.zip.CRC32;
 import java.util.zip.Deflater;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
@@ -46,7 +49,6 @@
 import org.apache.royale.compiler.exceptions.ConfigurationException;
 import org.apache.royale.compiler.exceptions.ConfigurationException.IOError;
 import org.apache.royale.compiler.exceptions.ConfigurationException.MustSpecifyTarget;
-import org.apache.royale.compiler.internal.codegen.js.JSWriter;
 import org.apache.royale.compiler.internal.driver.js.goog.JSGoogCompcConfiguration;
 import org.apache.royale.compiler.internal.projects.CompilerProject;
 import org.apache.royale.compiler.internal.targets.RoyaleSWCTarget;
@@ -167,7 +169,8 @@
      * @param args command line arguments
      * @return exit code
      */
-    private int _mainNoExit(final String[] args,
+    @SuppressWarnings("incomplete-switch")
+	private int _mainNoExit(final String[] args,
             List<ICompilerProblem> outProblems)
     {
     	System.out.println("args:");
@@ -184,9 +187,9 @@
 
             if (continueCompilation)
             {
-            	List<String> targets = config.getCompilerTargets();
-            	for (String target : targets)
-            		System.out.println("target:" + target);
+                List<String> targets = config.getCompilerTargets();
+                for (String target : targets)
+                    System.out.println("target:" + target);
             	targetloop:
             	for (String target : config.getCompilerTargets())
             	{
@@ -194,7 +197,7 @@
             		switch (JSTargetType.fromString(target))
 	                {
 	                case SWF:
-	                	System.out.println("COMPC");
+                        System.out.println("COMPC");
 	                    COMPC compc = new COMPC();
 	                    mxmlc = compc;
 	                    compc.configurationClass = JSGoogCompcConfiguration.class;
@@ -206,7 +209,7 @@
 	                    }
 	                    break;
 	                case JS_ROYALE:
-	                	System.out.println("COMPCJSCRoyale");
+                        System.out.println("COMPCJSCRoyale");
 	                	COMPJSCRoyale royale = new COMPJSCRoyale();
 	                	lastCompiler = royale;
 	                    result = royale.mainNoExit(removeASArgs(args), problems.getProblems(), false);
@@ -340,9 +343,18 @@
                         if (!entry.getName().contains("js/out") &&
                         	!entry.getName().contains(SWCReader.CATALOG_XML))
                         {
-                            System.out.println("Copy " + entry.getName());
+                            if (config.isVerbose())
+                            {
+                                System.out.println("Copy " + entry.getName());
+                            }
                         	InputStream input = zipFile.getInputStream(entry);
-                        	zipOutputStream.putNextEntry(new ZipEntry(entry.getName()));
+                        	ZipEntry ze = new ZipEntry(entry.getName());
+                        	ze.setMethod(ZipEntry.STORED);
+                        	ze.setTime(entry.getTime());
+                        	ze.setSize(entry.getSize());
+                        	ze.setCompressedSize(entry.getCompressedSize());
+                        	ze.setCrc(entry.getCrc());
+                        	zipOutputStream.putNextEntry(ze);
                         	IOUtils.copy(input, zipOutputStream);
                             zipOutputStream.flush();
                         	zipOutputStream.closeEntry();
@@ -395,7 +407,10 @@
 	                        final File outputClassFile = getOutputClassFile(
 	                                cu.getQualifiedNames().get(0), outputFolder, true);
 	
-	                        System.out.println("Compiling file: " + outputClassFile);
+                            if (config.isVerbose())
+                            {
+                                System.out.println("Compiling file: " + outputClassFile);
+                            }
 	
 	                        ICompilationUnit unit = cu;
 	
@@ -437,7 +452,10 @@
                     	}
                     	else
                     	{
-	                        System.out.println("Compiling file: " + cu.getQualifiedNames().get(0));
+	                        if (config.isVerbose())
+                            {
+                                System.out.println("Compiling file: " + cu.getQualifiedNames().get(0));
+                            }
 	                    	
 	                        ICompilationUnit unit = cu;
 	
@@ -457,37 +475,107 @@
 	                        problems.addAll(errors);
 	                        ByteArrayOutputStream temp = new ByteArrayOutputStream();
                             ByteArrayOutputStream sourceMapTemp = null;
-	                        if (project.config.getSourceMap())
+
+                            boolean isExterns = false;
+                            if(cu.getDefinitionPromises().size() > 0)
+                            {
+                                isExterns = project.isExterns(cu.getDefinitionPromises().get(0).getQualifiedName());
+                            }
+
+                            // if the file is @externs DON'T create source map file
+                            if (project.config.getSourceMap() && !isExterns)
 	                        {
                                 sourceMapTemp = new ByteArrayOutputStream();
 	                        }
                             writer.writeTo(temp, sourceMapTemp, null);
 
-                            boolean isExterns = false;
-	                        if (writer instanceof JSWriter)
-	                        	isExterns = ((JSWriter)writer).isExterns();
                     		String outputClassFile = getOutputClassFile(
                                     cu.getQualifiedNames().get(0),
                                     isExterns ? externsOut : jsOut,
                                     false).getPath();
-	                        System.out.println("Writing file: " + outputClassFile);     	
-	                        zipOutputStream.putNextEntry(new ZipEntry(outputClassFile));
-	                        temp.writeTo(zipOutputStream);
+                    		outputClassFile = outputClassFile.replace('\\', '/');
+	                        if (config.isVerbose())
+                            {
+                                System.out.println("Writing file: " + outputClassFile);     	
+                            }
+	                        long fileDate = System.currentTimeMillis();
+	                        long zipFileDate = fileDate;
+	                    	String metadataDate = targetSettings.getSWFMetadataDate();
+	                    	if (metadataDate != null)
+	                    	{
+	                    		String metadataFormat = targetSettings.getSWFMetadataDateFormat();
+	                    		try {
+	                    			SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
+	                    			fileDate = sdf.parse(metadataDate).getTime();
+	                    		} catch (ParseException e) {
+	                				// TODO Auto-generated catch block
+	                				e.printStackTrace();
+	                			} catch (IllegalArgumentException e1) {
+	                				e1.printStackTrace();
+	                			}
+	                    		// strip off timezone.  Zip format doesn't store timezone
+	                    		// and the goal is to have the same date and time regardless
+	                    		// of which timezone the build machine is using.
+	                    		int c = metadataDate.lastIndexOf(" ");
+	                    		metadataDate = metadataDate.substring(0,  c);
+	                    		c = metadataFormat.lastIndexOf(" ");
+	                    		metadataFormat = metadataFormat.substring(0, c);
+	                    		try {
+	                    			SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
+	                    			zipFileDate = sdf.parse(metadataDate).getTime();
+	                    		} catch (ParseException e) {
+	                				// TODO Auto-generated catch block
+	                				e.printStackTrace();
+	                			} catch (IllegalArgumentException e1) {
+	                				e1.printStackTrace();
+	                			}
+	                    	}
+	                    	ZipEntry ze = new ZipEntry(outputClassFile);
+	                    	ze.setTime(zipFileDate);
+	                    	ze.setMethod(ZipEntry.STORED);
+	                    	
+	                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+	                        temp.writeTo(baos);
+	                        ze.setSize(baos.size());
+	                        ze.setCompressedSize(baos.size());
+	                        CRC32 crc = new CRC32();
+	                        crc.reset();
+	                        crc.update(baos.toByteArray());
+	                        ze.setCrc(crc.getValue());
+
+	                        zipOutputStream.putNextEntry(ze);
+	                        baos.writeTo(zipOutputStream);
                             zipOutputStream.flush();
 	                        zipOutputStream.closeEntry();
-	                        fileList.append("        <file path=\"" + outputClassFile + "\" mod=\"" + System.currentTimeMillis() + "\"/>\n");
+	                        fileList.append("        <file path=\"" + outputClassFile + "\" mod=\"" + fileDate + "\"/>\n");
                             if(sourceMapTemp != null)
                             {
                                 String sourceMapFile = getOutputSourceMapFile(
                                     cu.getQualifiedNames().get(0),
                                     isExterns ? externsOut : jsOut,
                                     false).getPath();
-                                System.out.println("Writing file: " + sourceMapFile);     	
-                                zipOutputStream.putNextEntry(new ZipEntry(sourceMapFile));
-                                sourceMapTemp.writeTo(zipOutputStream);
+                                if (config.isVerbose())
+                                {
+                                    System.out.println("Writing file: " + sourceMapFile);
+                                }
+                                ze = new ZipEntry(sourceMapFile);
+    	                    	ze.setTime(zipFileDate);
+    	                    	ze.setMethod(ZipEntry.STORED);
+    	                    	
+    	                        baos = new ByteArrayOutputStream();
+                                sourceMapTemp.writeTo(baos);
+    	                        ze.setSize(baos.size());
+    	                        ze.setCompressedSize(baos.size());
+    	                        crc = new CRC32();
+    	                        crc.reset();
+    	                        crc.update(baos.toByteArray());
+    	                        ze.setCrc(crc.getValue());
+                                
+                                zipOutputStream.putNextEntry(ze);
+    	                        baos.writeTo(zipOutputStream);
                                 zipOutputStream.flush();
                                 zipOutputStream.closeEntry();
-                                fileList.append("        <file path=\"" + sourceMapFile + "\" mod=\"" + System.currentTimeMillis() + "\"/>\n");
+                                fileList.append("        <file path=\"" + sourceMapFile + "\" mod=\"" + fileDate + "\"/>\n");
                             }
                             writer.close();
                         }
@@ -496,12 +584,57 @@
                 if (packingSWC)
                 {
                 	zipFile.close();
+                    long fileDate = System.currentTimeMillis();
+                    long zipFileDate = fileDate;
+                	String metadataDate = targetSettings.getSWFMetadataDate();
+                	if (metadataDate != null)
+                	{
+                		String metadataFormat = targetSettings.getSWFMetadataDateFormat();
+                		try {
+                			SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
+                			fileDate = sdf.parse(metadataDate).getTime();
+                		} catch (ParseException e) {
+            				// TODO Auto-generated catch block
+            				e.printStackTrace();
+            			} catch (IllegalArgumentException e1) {
+            				e1.printStackTrace();
+            			}
+                		// strip off timezone.  Zip format doesn't store timezone
+                		// and the goal is to have the same date and time regardless
+                		// of which timezone the build machine is using.
+                		int c = metadataDate.lastIndexOf(" ");
+                		metadataDate = metadataDate.substring(0,  c);
+                		c = metadataFormat.lastIndexOf(" ");
+                		metadataFormat = metadataFormat.substring(0, c);
+                		try {
+                			SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
+                			zipFileDate = sdf.parse(metadataDate).getTime();
+                		} catch (ParseException e) {
+            				// TODO Auto-generated catch block
+            				e.printStackTrace();
+            			} catch (IllegalArgumentException e1) {
+            				e1.printStackTrace();
+            			}
+                	}
                 	int libraryIndex = catalog.indexOf("</libraries>");
                 	catalog = catalog.substring(0, libraryIndex + 13) +
                 		"    <files>\n" + fileList.toString() + "    </files>" + 
                 		catalog.substring(libraryIndex + 13);
-                    zipOutputStream.putNextEntry(new ZipEntry(SWCReader.CATALOG_XML));
-                	zipOutputStream.write(catalog.getBytes());
+                	ZipEntry ze = new ZipEntry(SWCReader.CATALOG_XML);
+                	ze.setTime(zipFileDate);
+                	ze.setMethod(ZipEntry.STORED);
+                	
+                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                	baos.write(catalog.getBytes());
+                    ze.setSize(baos.size());
+                    ze.setCompressedSize(baos.size());
+                    CRC32 crc = new CRC32();
+                    crc.reset();
+                    crc.update(baos.toByteArray());
+                    ze.setCrc(crc.getValue());
+                	
+                    zipOutputStream.putNextEntry(ze);
+                    baos.writeTo(zipOutputStream);
                     zipOutputStream.flush();
                     zipOutputStream.closeEntry();
                     zipOutputStream.flush();
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCNative.java b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCNative.java
index 8a13875..57d2ead 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCNative.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCNative.java
@@ -45,7 +45,6 @@
 import org.apache.royale.compiler.exceptions.ConfigurationException;
 import org.apache.royale.compiler.exceptions.ConfigurationException.IOError;
 import org.apache.royale.compiler.exceptions.ConfigurationException.MustSpecifyTarget;
-import org.apache.royale.compiler.internal.codegen.js.JSWriter;
 import org.apache.royale.compiler.internal.driver.mxml.jsc.MXMLJSCJSSWCBackend;
 import org.apache.royale.compiler.internal.parsing.as.RoyaleASDocDelegate;
 import org.apache.royale.compiler.internal.projects.CompilerProject;
@@ -203,7 +202,10 @@
                         if (!entry.getName().contains("js/out") &&
                         	!entry.getName().contains(SWCReader.CATALOG_XML))
                         {
-                            System.out.println("Copy " + entry.getName());
+                            if (config.isVerbose())
+                            {
+                                System.out.println("Copy " + entry.getName());
+                            }
                         	InputStream input = zipFile.getInputStream(entry);
                         	zipOutputStream.putNextEntry(new ZipEntry(entry.getName()));
                         	IOUtils.copy(input, zipOutputStream);
@@ -258,7 +260,10 @@
 	                        final File outputClassFile = getOutputClassFile(
 	                                cu.getQualifiedNames().get(0), outputFolder, true);
 	
-	                        System.out.println("Compiling file: " + outputClassFile);
+                            if (config.isVerbose())
+                            {
+                                System.out.println("Compiling file: " + outputClassFile);
+                            }
 	
 	                        ICompilationUnit unit = cu;
 	
@@ -300,7 +305,10 @@
                     	}
                     	else
                     	{
-	                        System.out.println("Compiling file: " + cu.getQualifiedNames().get(0));
+	                        if (config.isVerbose())
+                            {
+                                System.out.println("Compiling file: " + cu.getQualifiedNames().get(0));
+                            }
 	                    	
 	                        ICompilationUnit unit = cu;
 	
@@ -321,20 +329,28 @@
 
                             ByteArrayOutputStream temp = new ByteArrayOutputStream();
                             ByteArrayOutputStream sourceMapTemp = null;
-	                        if (project.config.getSourceMap())
+                            
+                            boolean isExterns = false;
+                            if(cu.getDefinitionPromises().size() > 0)
+                            {
+                                isExterns = project.isExterns(cu.getDefinitionPromises().get(0).getQualifiedName());
+                            }
+
+                            // if the file is @externs DON'T create source map file
+	                        if (project.config.getSourceMap() && !isExterns)
 	                        {
                                 sourceMapTemp = new ByteArrayOutputStream();
 	                        }
                             writer.writeTo(temp, sourceMapTemp, null);
 
-                            boolean isExterns = false;
-	                        if (writer instanceof JSWriter)
-	                        	isExterns = ((JSWriter)writer).isExterns();
                     		String outputClassFile = getOutputClassFile(
                                     cu.getQualifiedNames().get(0),
                                     isExterns ? externsOut : jsOut,
                                     false).getPath();
-	                        System.out.println("Writing file: " + outputClassFile);     	
+                            if (config.isVerbose())
+                            {
+                                System.out.println("Writing file: " + outputClassFile);     	
+                            }
 	                        zipOutputStream.putNextEntry(new ZipEntry(outputClassFile));
 	                        temp.writeTo(zipOutputStream);
                             zipOutputStream.flush();
@@ -346,7 +362,10 @@
                                     cu.getQualifiedNames().get(0),
                                     isExterns ? externsOut : jsOut,
                                     false).getPath();
-                                System.out.println("Writing file: " + sourceMapFile);     	
+                                if (config.isVerbose())
+                                {
+                                    System.out.println("Writing file: " + sourceMapFile);
+                                }
                                 zipOutputStream.putNextEntry(new ZipEntry(sourceMapFile));
                                 sourceMapTemp.writeTo(zipOutputStream);
                                 zipOutputStream.flush();
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCRoyale.java b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCRoyale.java
index 481ec55..1ca37df 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCRoyale.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCRoyale.java
@@ -26,11 +26,14 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Enumeration;
 import java.util.List;
 import java.util.Set;
+import java.util.zip.CRC32;
 import java.util.zip.Deflater;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
@@ -45,7 +48,6 @@
 import org.apache.royale.compiler.exceptions.ConfigurationException;
 import org.apache.royale.compiler.exceptions.ConfigurationException.IOError;
 import org.apache.royale.compiler.exceptions.ConfigurationException.MustSpecifyTarget;
-import org.apache.royale.compiler.internal.codegen.js.JSWriter;
 import org.apache.royale.compiler.internal.driver.mxml.royale.MXMLRoyaleSWCBackend;
 import org.apache.royale.compiler.internal.parsing.as.RoyaleASDocDelegate;
 import org.apache.royale.compiler.internal.projects.CompilerProject;
@@ -204,9 +206,50 @@
                         if (!entry.getName().contains("js/out") &&
                         	!entry.getName().contains(SWCReader.CATALOG_XML))
                         {
-                            System.out.println("Copy " + entry.getName());
+                            if (config.isVerbose())
+                            {
+                                System.out.println("Copy " + entry.getName());
+                            }
                         	InputStream input = zipFile.getInputStream(entry);
-                        	zipOutputStream.putNextEntry(new ZipEntry(entry.getName()));
+                        	ZipEntry ze = new ZipEntry(entry.getName());
+                        	ze.setMethod(ZipEntry.STORED);
+                        	ze.setSize(entry.getSize());
+                        	ze.setCompressedSize(entry.getCompressedSize());
+                        	ze.setCrc(entry.getCrc());
+	                        long fileDate = System.currentTimeMillis();
+	                        long zipFileDate = fileDate;
+	                    	String metadataDate = targetSettings.getSWFMetadataDate();
+	                    	if (metadataDate != null)
+	                    	{
+	                    		String metadataFormat = targetSettings.getSWFMetadataDateFormat();
+	                    		try {
+	                    			SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
+	                    			fileDate = sdf.parse(metadataDate).getTime();
+	                    		} catch (ParseException e) {
+	                				// TODO Auto-generated catch block
+	                				e.printStackTrace();
+	                			} catch (IllegalArgumentException e1) {
+	                				e1.printStackTrace();
+	                			}
+	                    		// strip off timezone.  Zip format doesn't store timezone
+	                    		// and the goal is to have the same date and time regardless
+	                    		// of which timezone the build machine is using.
+	                    		int c = metadataDate.lastIndexOf(" ");
+	                    		metadataDate = metadataDate.substring(0,  c);
+	                    		c = metadataFormat.lastIndexOf(" ");
+	                    		metadataFormat = metadataFormat.substring(0, c);
+	                    		try {
+	                    			SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
+	                    			zipFileDate = sdf.parse(metadataDate).getTime();
+	                    		} catch (ParseException e) {
+	                				// TODO Auto-generated catch block
+	                				e.printStackTrace();
+	                			} catch (IllegalArgumentException e1) {
+	                				e1.printStackTrace();
+	                			}
+	                    	}
+	                    	ze.setTime(zipFileDate);
+                        	zipOutputStream.putNextEntry(ze);
                         	IOUtils.copy(input, zipOutputStream);
                             zipOutputStream.flush();
                         	zipOutputStream.closeEntry();
@@ -259,7 +302,10 @@
 	                        final File outputClassFile = getOutputClassFile(
 	                                cu.getQualifiedNames().get(0), outputFolder, true);
 	
-	                        System.out.println("Compiling file: " + outputClassFile);
+                            if (config.isVerbose())
+                            {
+                                System.out.println("Compiling file: " + outputClassFile);
+                            }
 	
 	                        ICompilationUnit unit = cu;
 	
@@ -300,7 +346,10 @@
                     	}
                     	else
                     	{
-	                        System.out.println("Compiling file: " + cu.getQualifiedNames().get(0));
+	                        if (config.isVerbose())
+                            {
+                                System.out.println("Compiling file: " + cu.getQualifiedNames().get(0));
+                            }
 	                    	
 	                        ICompilationUnit unit = cu;
 	
@@ -320,37 +369,108 @@
 
                             ByteArrayOutputStream temp = new ByteArrayOutputStream();
                             ByteArrayOutputStream sourceMapTemp = null;
-	                        if (project.config.getSourceMap())
+                            
+                            boolean isExterns = false;
+                            if(cu.getDefinitionPromises().size() > 0)
+                            {
+                                isExterns = project.isExterns(cu.getDefinitionPromises().get(0).getQualifiedName());
+                            }
+	                        
+                            // if the file is @externs DON'T create source map file
+                            if (project.config.getSourceMap() && !isExterns)
 	                        {
                                 sourceMapTemp = new ByteArrayOutputStream();
 	                        }
                             writer.writeTo(temp, sourceMapTemp, null);
 
-                            boolean isExterns = false;
-	                        if (writer instanceof JSWriter)
-	                        	isExterns = ((JSWriter)writer).isExterns();
                     		String outputClassFile = getOutputClassFile(
                                     cu.getQualifiedNames().get(0),
                                     isExterns ? externsOut : jsOut,
                                     false).getPath();
-	                        System.out.println("Writing file: " + outputClassFile);     	
-	                        zipOutputStream.putNextEntry(new ZipEntry(outputClassFile));
-	                        temp.writeTo(zipOutputStream);
+                    		outputClassFile = outputClassFile.replace('\\', '/');
+	                        if (config.isVerbose())
+                            {
+                                System.out.println("Writing file: " + outputClassFile);     	
+                            }
+	                        long fileDate = System.currentTimeMillis();
+	                        long zipFileDate = fileDate;
+	                    	String metadataDate = targetSettings.getSWFMetadataDate();
+	                    	if (metadataDate != null)
+	                    	{
+	                    		String metadataFormat = targetSettings.getSWFMetadataDateFormat();
+	                    		try {
+	                    			SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
+	                    			fileDate = sdf.parse(metadataDate).getTime();
+	                    		} catch (ParseException e) {
+	                				// TODO Auto-generated catch block
+	                				e.printStackTrace();
+	                			} catch (IllegalArgumentException e1) {
+	                				e1.printStackTrace();
+	                			}
+	                    		// strip off timezone.  Zip format doesn't store timezone
+	                    		// and the goal is to have the same date and time regardless
+	                    		// of which timezone the build machine is using.
+	                    		int c = metadataDate.lastIndexOf(" ");
+	                    		metadataDate = metadataDate.substring(0,  c);
+	                    		c = metadataFormat.lastIndexOf(" ");
+	                    		metadataFormat = metadataFormat.substring(0, c);
+	                    		try {
+	                    			SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
+	                    			zipFileDate = sdf.parse(metadataDate).getTime();
+	                    		} catch (ParseException e) {
+	                				// TODO Auto-generated catch block
+	                				e.printStackTrace();
+	                			} catch (IllegalArgumentException e1) {
+	                				e1.printStackTrace();
+	                			}
+	                    	}
+	                    	ZipEntry ze = new ZipEntry(outputClassFile);
+	                    	ze.setTime(zipFileDate);
+	                    	ze.setMethod(ZipEntry.STORED);
+	                    	
+	                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+	                        temp.writeTo(baos);
+	                        ze.setSize(baos.size());
+	                        ze.setCompressedSize(baos.size());
+	                        CRC32 crc = new CRC32();
+	                        crc.reset();
+	                        crc.update(baos.toByteArray());
+	                        ze.setCrc(crc.getValue());
+
+	                        zipOutputStream.putNextEntry(ze);
+	                        baos.writeTo(zipOutputStream);
                             zipOutputStream.flush();
                             zipOutputStream.closeEntry();
-	                        fileList.append("        <file path=\"" + outputClassFile + "\" mod=\"" + System.currentTimeMillis() + "\"/>\n");
+                            fileList.append("        <file path=\"" + outputClassFile + "\" mod=\"" + fileDate + "\"/>\n");
+                            
                             if(sourceMapTemp != null)
                             {
                                 String sourceMapFile = getOutputSourceMapFile(
-                                    cu.getQualifiedNames().get(0),
-                                    isExterns ? externsOut : jsOut,
-                                    false).getPath();
-                                System.out.println("Writing file: " + sourceMapFile);     	
-                                zipOutputStream.putNextEntry(new ZipEntry(sourceMapFile));
-                                sourceMapTemp.writeTo(zipOutputStream);
+                                                                                cu.getQualifiedNames().get(0),
+                                                                                isExterns ? externsOut : jsOut,
+                                                                                false).getPath();
+                                if (config.isVerbose())
+                                {
+                                    System.out.println("Writing file: " + sourceMapFile);
+                                }
+                                ze = new ZipEntry(sourceMapFile);
+                                ze.setTime(zipFileDate);
+                                ze.setMethod(ZipEntry.STORED);
+                                
+                                baos = new ByteArrayOutputStream();
+                                sourceMapTemp.writeTo(baos);
+                                ze.setSize(baos.size());
+                                ze.setCompressedSize(baos.size());
+                                crc = new CRC32();
+                                crc.reset();
+                                crc.update(baos.toByteArray());
+                                ze.setCrc(crc.getValue());
+                                
+                                zipOutputStream.putNextEntry(ze);
+                                baos.writeTo(zipOutputStream);
                                 zipOutputStream.flush();
                                 zipOutputStream.closeEntry();
-                                fileList.append("        <file path=\"" + sourceMapFile + "\" mod=\"" + System.currentTimeMillis() + "\"/>\n");
+                                fileList.append("        <file path=\"" + sourceMapFile + "\" mod=\"" + fileDate + "\"/>\n");
                             }
 	                        writer.close();
                     	}
@@ -367,12 +487,57 @@
                 if (packingSWC)
                 {
                 	zipFile.close();
+                    long fileDate = System.currentTimeMillis();
+                    long zipFileDate = fileDate;
+                	String metadataDate = targetSettings.getSWFMetadataDate();
+                	if (metadataDate != null)
+                	{
+                		String metadataFormat = targetSettings.getSWFMetadataDateFormat();
+                		try {
+                			SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
+                			fileDate = sdf.parse(metadataDate).getTime();
+                		} catch (ParseException e) {
+            				// TODO Auto-generated catch block
+            				e.printStackTrace();
+            			} catch (IllegalArgumentException e1) {
+            				e1.printStackTrace();
+            			}
+                		// strip off timezone.  Zip format doesn't store timezone
+                		// and the goal is to have the same date and time regardless
+                		// of which timezone the build machine is using.
+                		int c = metadataDate.lastIndexOf(" ");
+                		metadataDate = metadataDate.substring(0,  c);
+                		c = metadataFormat.lastIndexOf(" ");
+                		metadataFormat = metadataFormat.substring(0, c);
+                		try {
+                			SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
+                			zipFileDate = sdf.parse(metadataDate).getTime();
+                		} catch (ParseException e) {
+            				// TODO Auto-generated catch block
+            				e.printStackTrace();
+            			} catch (IllegalArgumentException e1) {
+            				e1.printStackTrace();
+            			}
+                	}
                 	int libraryIndex = catalog.indexOf("</libraries>");
                 	catalog = catalog.substring(0, libraryIndex + 13) +
                 		"    <files>\n" + fileList.toString() + "    </files>" + 
                 		catalog.substring(libraryIndex + 13);
-                    zipOutputStream.putNextEntry(new ZipEntry(SWCReader.CATALOG_XML));
-                	zipOutputStream.write(catalog.getBytes());
+                	ZipEntry ze = new ZipEntry(SWCReader.CATALOG_XML);
+                	ze.setTime(zipFileDate);
+                	ze.setMethod(ZipEntry.STORED);
+                	
+                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                	baos.write(catalog.getBytes());
+                    ze.setSize(baos.size());
+                    ze.setCompressedSize(baos.size());
+                    CRC32 crc = new CRC32();
+                    crc.reset();
+                    crc.update(baos.toByteArray());
+                    ze.setCrc(crc.getValue());
+                	
+                    zipOutputStream.putNextEntry(ze);
+                    baos.writeTo(zipOutputStream);
                     zipOutputStream.flush();
                     zipOutputStream.closeEntry();
                     zipOutputStream.flush();
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/JSConfiguration.java b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/JSConfiguration.java
index 22854f4..eda4012 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/JSConfiguration.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/JSConfiguration.java
@@ -49,13 +49,16 @@
  * configure() method of {@link MXMLJSC}.
  * <p>
  * This class inherits all compiler arguments from the MXMLC compiler.
- * 
+ *
  * @author Michael Schmalle
  */
 public class JSConfiguration extends Configuration
 {
     public JSConfiguration()
     {
+        setCompilerAllowAbstractClasses(null, true);
+        setCompilerAllowPrivateConstructors(null, true);
+        setCompilerAllowImportAliases(null, true);
     }
 
     //
@@ -123,7 +126,7 @@
     // 'js-default-initializers'
     //
 
-    private boolean jsDefaultInitializers = false;
+    private boolean jsDefaultInitializers = true;
 
     public boolean getJsDefaultInitializers()
     {
@@ -153,7 +156,7 @@
      * If the definition of a member cannot be resolved, emit dynamic access
      * instead of normal member access. Ensures that dynamic members aren't
      * renamed.
-     * 
+     *
      * <code>myObject.memberAccess</code> becomes <code>myObject["memberAccess"]</code>
      */
     @Config
@@ -222,7 +225,7 @@
      * Example: <code>-define=CONFIG::debugging,true</code>
      *
      * In <code>royale-config.xml</code>:<br/>
-     * 
+     *
      * <pre>
      * <royale-config>
      *    <compiler>
@@ -251,7 +254,7 @@
      * <code>"\"foo\""</code> or <code>"\'foo\'"</code>) or single-quoted (<code>"'foo'"</code>).
      *
      * String values in configuration files need only be single- or double- quoted:<br/>
-     * 
+     *
      * <pre>
      * <royale-config>
      *    <compiler>
@@ -270,18 +273,18 @@
      *
      * Empty strings <i>must</i> be passed as <code>"''"</code> on the command-line, and <code>''</code> or
      * <code>""</code> in configuration files.
-     * 
+     *
      * Finally, if you have existing definitions in a configuration file, and you would like to add to them with the
      * command-line (let's say most of your build setCompilertings are in the configuration, and that you are adding one
      * temporarily using the command-line), you use the following syntax: <code>-define+=TEST::temporary,false</code>
      * (noting the plus sign)
-     * 
+     *
      * Note that definitions can be overridden/redefined if you use the append ("+=") syntax (on the commandline or in a
      * user config file, for instance) with the same namespace and name, and a new value.
-     * 
+     *
      * Definitions cannot be removed/undefined. You can undefine ALL existing definitions from (e.g. from
      * royale-config.xml) if you do not use append syntax ("=" or append="false").
-     * 
+     *
      * IMPORTANT FOR FLASH BUILDER If you are using "Additional commandline arguments" to "-define", don't use the
      * following syntax though I suggest it above: -define+=CONFIG::foo,"'value'" The trouble is that FB parses the
      * double quotes incorrectly as <"'value'> -- the trailing double-quote is dropped. The solution is to avoid inner
@@ -382,7 +385,7 @@
     @Arguments("filename")
     public void setJsLoadConfig(ConfigurationValue cv, String filename) throws ConfigurationException
     {
-        
+    
     }
     
     //////////////////////////////////////////////////////////////////////////
@@ -400,7 +403,7 @@
      * Configures a list of many manifests mapped to a single namespace URI.
      * <namespace> <uri>library:adobe/flex/something</uri> <manifest>something-manifest.xml</manifest>
      * <manifest>something-else-manifest.xml</manifest> ... </namespace>
-     * 
+     *
      * @param cfgval The configuration value context.
      * @param args A List of values for the namespace element, with the first item expected to be the uri and the
      *        remaining are manifest paths.
@@ -442,4 +445,140 @@
         }
     }
 
+    //
+    // 'js-vector-emulation-class' option
+    //
+
+    private String jsVectorEmulationClass = null;
+
+    public String getJsVectorEmulationClass()
+    {
+        return jsVectorEmulationClass;
+    }
+
+    /**
+     * The class to use instead of default Vector implementation for handling Vector.
+     */
+    @Config(advanced = true)
+    public void setJsVectorEmulationClass(ConfigurationValue cv, String b)
+    {
+    	jsVectorEmulationClass = b;
+    }
+    
+    
+    //
+    // 'js-complex-implicit-coercions'
+    //
+    
+    private boolean jsComplexImplicitCoercions = true;
+    
+    public boolean getJsComplexImplicitCoercions()
+    {
+        return jsComplexImplicitCoercions;
+    }
+    
+    /**
+     * Support for including/avoiding more complex implicit assignment coercions
+     * example
+     * var array:Array = [new MyClass()];
+     * var myOtherClass:MyOtherClass = array[0];
+     *
+     * In the above example, the compiler will (by default) output an implicit coercion
+     * that is equivalent in actionscript to:
+     * var myOtherClass:MyOtherClass = MyOtherClass(array[0]);
+     *
+     * By setting this configuration option to false, the implicit coercion code in situations similar to the above
+     * is not generated (other primitive implicit coercions, such as int/uint/Number/String and Boolean coercions remain)
+     * This is a global setting for the current source code being compiled, it is possible to leave it on and specifically avoid it via doc
+     * settings. The doc comment compiler directive for that is: @royalesuppresscompleximplicitcoercion
+     * Another option is to add the explicit coercions in code and then avoid their output
+     * via specific @royaleignorecoercion doc comment directives. Doing so however may add extra unwanted output
+     * in other compiler targets (for example, swf bytecode) if the same source code is shared between targets.
+     */
+    @Config(advanced = true)
+    @Mapping("js-complex-implicit-coercions")
+    public void setJsComplexImplicitCoercions(ConfigurationValue cv, boolean value)
+            throws ConfigurationException
+    {
+        jsComplexImplicitCoercions = value;
+    }
+    
+    //
+    // 'js-resolve-uncertain'
+    //
+    
+    private boolean jsResolveUncertain = true;
+    
+    public boolean getJsResolveUncertain()
+    {
+        return jsResolveUncertain;
+    }
+    
+    /**
+     * Support for avoiding more overhead of resolving instantiations from
+     * unknown constructors
+     * example
+     * var myClass:Class = String;
+     * var myString:* = new myClass("test");
+     *
+     * In the above example, the compiler will (by default) output
+     * a call to a Language.resolveUncertain method which wraps the 'new myClass("test")'
+     *
+     *
+     * This normalizes the return value for some primitive constructors, so that (for example)
+     * strict equality and inequality operators provide the same results between compiler
+     * targets.
+     * In situations where it is certain that the resolveUncertain method is not needed,
+     * this option provides a way to switch it off 'globally' for the current source code being compiled.
+     * It can also be switched off or on locally using the '@royalesuppressresolveuncertain'
+     * doc comment compiler directive.
+     */
+    @Config(advanced = true)
+    @Mapping("js-resolve-uncertain")
+    public void setJsResolveUncertain(ConfigurationValue cv, boolean value)
+            throws ConfigurationException
+    {
+        jsResolveUncertain = value;
+    }
+    
+    //
+    // 'js-vector-index-checks'
+    //
+    
+    private boolean jsVectorIndexChecks = true;
+    
+    public boolean getJsVectorIndexChecks()
+    {
+        return jsVectorIndexChecks;
+    }
+    
+    /**
+     * Support for avoiding more overhead of adding checks into
+     * assignments via Vector index access
+     * example
+     * var myVector:Vector.<int> = new Vector.<int>();
+     * myVector[0] = 42;
+     *
+     * In the above example, the compiler will (by default) wrap
+     * the '0' inside myVector[0] with a method call on the vector instance
+     * that checks to see if the index is valid for the Vector it is being used against
+     *
+     * This check will throw an error if the index is out of range, and the
+     * range checking differs if the Vector is 'fixed' or non-'fixed'
+     *
+     * In situations where it is certain that the index will always be valid for Vector instance
+     * being targeted, or where all cases in a given codebase are certain to be valid, it is possible
+     * to avoid the overhead of this check. This is especially important in loops.
+     * This config setting affects the global setting for the current source code being compiled.
+     * It can be adjusted locally within code, using the '@royalesuppressvectorindexcheck'
+     * doc comment compiler  directive.
+     */
+    @Config(advanced = true)
+    @Mapping("js-vector-index-checks")
+    public void setJsVectorIndexChecks(ConfigurationValue cv, boolean value)
+            throws ConfigurationException
+    {
+        jsVectorIndexChecks = value;
+    }
+    
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSC.java b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSC.java
index 8129274..b8cb3fb 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSC.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSC.java
@@ -25,6 +25,8 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -58,6 +60,7 @@
 import org.apache.royale.compiler.exceptions.ConfigurationException.OnlyOneSource;
 import org.apache.royale.compiler.internal.config.FlashBuilderConfigurator;
 import org.apache.royale.compiler.internal.config.localization.LocalizationManager;
+import org.apache.royale.compiler.internal.definitions.DefinitionBase;
 import org.apache.royale.compiler.internal.driver.js.goog.JSGoogConfiguration;
 import org.apache.royale.compiler.internal.parsing.as.RoyaleASDocDelegate;
 import org.apache.royale.compiler.internal.projects.CompilerProject;
@@ -188,7 +191,7 @@
     {
         SUCCESS(0),
         PRINT_HELP(1),
-        FAILED_WITH_PROBLEMS(2),
+        FAILED_WITH_PROBLEMS(0),
         FAILED_WITH_ERRORS(3),
         FAILED_WITH_EXCEPTIONS(4),
         FAILED_WITH_CONFIG_PROBLEMS(5);
@@ -285,6 +288,7 @@
     
     public MXMLJSC()
     {
+        DefinitionBase.setPerformanceCachingEnabled(true);
         workspace = new Workspace();
         workspace.setASDocDelegate(new RoyaleASDocDelegate());
         project = new RoyaleJSProject(workspace, null);
@@ -464,8 +468,11 @@
     			  arg.startsWith("-compiler.js-library-path") ||
     			  arg.startsWith("-compiler.js-define") ||
     			  arg.startsWith("-js-output") ||
+    			  arg.startsWith("-js-vector-emulation-class") ||
+    			  arg.startsWith("-externs-report") ||
     			  arg.startsWith("-js-load-config") ||
     			  arg.startsWith("-warn-public-vars") ||
+    			  arg.startsWith("-export-protected-symbols") ||
     			  arg.startsWith("-source-map")))
     			list.add(arg);						
     	}
@@ -558,7 +565,10 @@
 	                        final File outputClassFile = getOutputClassFile(
 	                                cu.getQualifiedNames().get(0), outputFolder);
 	
-	                        System.out.println("Compiling file: " + outputClassFile);
+                            if (config.isVerbose())
+                            {
+                                System.out.println("Compiling file: " + outputClassFile);
+                            }
 
 	                        ICompilationUnit unit = cu;
 	
@@ -596,6 +606,22 @@
                                 sourceMapOut.close();
                             }
 	                        writer.close();
+	                        long fileDate = 0;
+	                    	String metadataDate = targetSettings.getSWFMetadataDate();
+	                    	if (metadataDate != null)
+	                    	{
+	                    		String metadataFormat = targetSettings.getSWFMetadataDateFormat();
+	                    		try {
+	                    			SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
+	                    			fileDate = sdf.parse(metadataDate).getTime();
+	                    		} catch (ParseException e) {
+	                				// TODO Auto-generated catch block
+	                				e.printStackTrace();
+	                			} catch (IllegalArgumentException e1) {
+	                				e1.printStackTrace();
+	                			}
+	                    		outputClassFile.setLastModified(fileDate);
+	                    	}
 	                    }
 	                }
                 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCNative.java b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCNative.java
index 6bae88f..1c4474f 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCNative.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCNative.java
@@ -49,6 +49,7 @@
 import org.apache.royale.compiler.exceptions.ConfigurationException.MustSpecifyTarget;
 import org.apache.royale.compiler.exceptions.ConfigurationException.OnlyOneSource;
 import org.apache.royale.compiler.internal.config.FlashBuilderConfigurator;
+import org.apache.royale.compiler.internal.definitions.DefinitionBase;
 import org.apache.royale.compiler.internal.driver.js.goog.JSGoogConfiguration;
 import org.apache.royale.compiler.internal.driver.js.jsc.JSCBackend;
 import org.apache.royale.compiler.internal.parsing.as.RoyaleASDocDelegate;
@@ -99,7 +100,7 @@
     {
         SUCCESS(0),
         PRINT_HELP(1),
-        FAILED_WITH_PROBLEMS(2),
+        FAILED_WITH_PROBLEMS(0),
         FAILED_WITH_ERRORS(3),
         FAILED_WITH_EXCEPTIONS(4),
         FAILED_WITH_CONFIG_PROBLEMS(5);
@@ -174,6 +175,7 @@
     {
         IBackend backend = new JSCBackend();
 
+        DefinitionBase.setPerformanceCachingEnabled(true);
         workspace = new Workspace();
         workspace.setASDocDelegate(new RoyaleASDocDelegate());
         project = new RoyaleJSProject(workspace, backend);
@@ -337,7 +339,10 @@
 	                        final File outputClassFile = getOutputClassFile(
 	                                cu.getQualifiedNames().get(0), outputFolder);
 	
-	                        System.out.println("Compiling file: " + outputClassFile);
+                            if (config.isVerbose())
+                            {
+                                System.out.println("Compiling file: " + outputClassFile);
+                            }
 	
 	                        ICompilationUnit unit = cu;
 	
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCNode.java b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCNode.java
index ed98d56..bb83228 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCNode.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCNode.java
@@ -49,6 +49,7 @@
 import org.apache.royale.compiler.exceptions.ConfigurationException.MustSpecifyTarget;
 import org.apache.royale.compiler.exceptions.ConfigurationException.OnlyOneSource;
 import org.apache.royale.compiler.internal.config.FlashBuilderConfigurator;
+import org.apache.royale.compiler.internal.definitions.DefinitionBase;
 import org.apache.royale.compiler.internal.driver.js.goog.JSGoogConfiguration;
 import org.apache.royale.compiler.internal.driver.js.node.NodeBackend;
 import org.apache.royale.compiler.internal.parsing.as.RoyaleASDocDelegate;
@@ -98,7 +99,7 @@
     {
         SUCCESS(0),
         PRINT_HELP(1),
-        FAILED_WITH_PROBLEMS(2),
+        FAILED_WITH_PROBLEMS(0),
         FAILED_WITH_ERRORS(3),
         FAILED_WITH_EXCEPTIONS(4),
         FAILED_WITH_CONFIG_PROBLEMS(5);
@@ -176,6 +177,7 @@
     
     protected MXMLJSCNode(IBackend backend)
     {
+        DefinitionBase.setPerformanceCachingEnabled(true);
         workspace = new Workspace();
         workspace.setASDocDelegate(new RoyaleASDocDelegate());
         project = new RoyaleJSProject(workspace, backend);
@@ -339,7 +341,10 @@
 	                        final File outputClassFile = getOutputClassFile(
 	                                cu.getQualifiedNames().get(0), outputFolder);
 	
-	                        System.out.println("Compiling file: " + outputClassFile);
+                            if (config.isVerbose())
+                            {
+                                System.out.println("Compiling file: " + outputClassFile);
+                            }
 	
 	                        ICompilationUnit unit = cu;
 	
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCRoyale.java b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCRoyale.java
index 66a2989..fe7c209 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCRoyale.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCRoyale.java
@@ -22,12 +22,15 @@
 import java.io.BufferedOutputStream;
 import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -44,24 +47,34 @@
 import org.apache.royale.compiler.clients.problems.WorkspaceProblemFormatter;
 import org.apache.royale.compiler.codegen.js.IJSPublisher;
 import org.apache.royale.compiler.codegen.js.IJSWriter;
-import org.apache.royale.compiler.config.CompilerDiagnosticsConstants;
 import org.apache.royale.compiler.config.Configuration;
 import org.apache.royale.compiler.config.ConfigurationBuffer;
 import org.apache.royale.compiler.config.Configurator;
 import org.apache.royale.compiler.config.ICompilerSettingsConstants;
+import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.driver.IBackend;
 import org.apache.royale.compiler.driver.js.IJSApplication;
 import org.apache.royale.compiler.exceptions.ConfigurationException;
 import org.apache.royale.compiler.exceptions.ConfigurationException.IOError;
 import org.apache.royale.compiler.exceptions.ConfigurationException.MustSpecifyTarget;
 import org.apache.royale.compiler.exceptions.ConfigurationException.OnlyOneSource;
+import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogDocEmitter;
 import org.apache.royale.compiler.internal.config.FlashBuilderConfigurator;
+import org.apache.royale.compiler.internal.definitions.AccessorDefinition;
+import org.apache.royale.compiler.internal.definitions.ClassDefinition;
+import org.apache.royale.compiler.internal.definitions.DefinitionBase;
+import org.apache.royale.compiler.internal.definitions.FunctionDefinition;
+import org.apache.royale.compiler.internal.definitions.InterfaceDefinition;
+import org.apache.royale.compiler.internal.definitions.ParameterDefinition;
 import org.apache.royale.compiler.internal.driver.js.goog.JSGoogConfiguration;
 import org.apache.royale.compiler.internal.driver.mxml.royale.MXMLRoyaleBackend;
 import org.apache.royale.compiler.internal.parsing.as.RoyaleASDocDelegate;
 import org.apache.royale.compiler.internal.projects.CompilerProject;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
 import org.apache.royale.compiler.internal.projects.ISourceFileHandler;
+import org.apache.royale.compiler.internal.scopes.ASProjectScope.DefinitionPromise;
+import org.apache.royale.compiler.internal.scopes.ASScope;
 import org.apache.royale.compiler.internal.targets.RoyaleJSTarget;
 import org.apache.royale.compiler.internal.targets.JSTarget;
 import org.apache.royale.compiler.internal.units.ResourceBundleCompilationUnit;
@@ -74,6 +87,7 @@
 import org.apache.royale.compiler.problems.UnableToBuildSWFProblem;
 import org.apache.royale.compiler.problems.UnexpectedExceptionProblem;
 import org.apache.royale.compiler.projects.ICompilerProject;
+import org.apache.royale.compiler.scopes.IDefinitionSet;
 import org.apache.royale.compiler.targets.ITarget;
 import org.apache.royale.compiler.targets.ITarget.TargetType;
 import org.apache.royale.compiler.targets.ITargetSettings;
@@ -110,7 +124,7 @@
     {
         SUCCESS(0),
         PRINT_HELP(1),
-        FAILED_WITH_PROBLEMS(2),
+        FAILED_WITH_PROBLEMS(0),
         FAILED_WITH_ERRORS(3),
         FAILED_WITH_EXCEPTIONS(4),
         FAILED_WITH_CONFIG_PROBLEMS(5);
@@ -190,6 +204,7 @@
     
     public MXMLJSCRoyale(IBackend backend)
     {
+        DefinitionBase.setPerformanceCachingEnabled(true);
         workspace = new Workspace();
         workspace.setASDocDelegate(new RoyaleASDocDelegate());
         project = new RoyaleJSProject(workspace, backend);
@@ -363,8 +378,11 @@
 	                    {
 	                        final File outputClassFile = getOutputClassFile(
 	                                cu.getQualifiedNames().get(0), outputFolder);
-	
-	                        System.out.println("Compiling file: " + outputClassFile);
+    
+                            if (config.isVerbose())
+                            {
+                                System.out.println("Compiling file: " + outputClassFile);
+                            }
 	
 	                        ICompilationUnit unit = cu;
 	
@@ -404,6 +422,9 @@
 	                        writer.close();
 	                    }
 	                }
+	                File externsReportFile = googConfiguration.getExternsReport();
+	                if (externsReportFile != null)
+	                	generateExternsReport(externsReportFile, reachableCompilationUnits, problems);
                 }
                 
                 if (!config.getCreateTargetWithErrors())
@@ -437,99 +458,374 @@
         return compilationSuccess && (errs.size() == 0);
     }
 
-    private void outputResourceBundle(ResourceBundleCompilationUnit cu, File outputFolder) {
+    private void generateExternsReport(File externsReportFile,
+			List<ICompilationUnit> reachableCompilationUnits,
+			ProblemQuery problems) {
+        
+        if (config.isVerbose())
+        {
+            System.out.println("Generating externs report: " + externsReportFile.getAbsolutePath());
+        }
+        
+    	ArrayList<String> packageNames = new ArrayList<String>();
+    	ArrayList<String> partNames = new ArrayList<String>();
+    	
+    	StringBuilder sb = new StringBuilder();
+        sb.append("/**\n");
+        sb.append(" * Generated by Apache Royale Compiler\n");
+        sb.append(" *\n");
+        sb.append(" * @fileoverview\n");
+        sb.append(" * @externs\n");
+        sb.append(" *\n");
+        // need to suppress access controls so access to protected/private from defineProperties
+        // doesn't generate warnings.
+        sb.append(" * @suppress {checkTypes|accessControls}\n");
+        sb.append(" */\n");
+
+    	for (ICompilationUnit cu : reachableCompilationUnits)
+    	{
+    		if (project.isExternalLinkage(cu)) continue;
+    		
+            List<IDefinition> dp = cu.getDefinitionPromises();
+
+            if (dp.size() == 0)
+                return;
+
+            IDefinition def = dp.get(0);
+            IDefinition actualDef = ((DefinitionPromise) def).getActualDefinition();
+            if (actualDef.getPackageName().contains("goog")) continue;
+            if (actualDef instanceof ClassDefinition)
+            {
+            	sb.append("\n\n");
+            	ClassDefinition cdef = (ClassDefinition)actualDef;
+            	String pkgName = cdef.getPackageName();
+            	if (pkgName.length() > 0 && !packageNames.contains(pkgName))
+            	{
+            		packageNames.add(pkgName);
+            		String[] parts = pkgName.split("\\.");
+            		String current = "";
+            		boolean firstOne = true;
+            		for (String part : parts)
+            		{
+            			current += part;
+            			if (partNames.contains(current))
+            			{
+            				firstOne = false;
+        	                current += ".";
+            				continue;
+            			}            			
+            			partNames.add(current);
+        				sb.append("/**\n * @suppress {duplicate}\n * @const\n */\n");
+            			if (firstOne)
+            			{
+            				sb.append("var ");
+            				firstOne = false;
+            			}
+            			sb.append(current);
+            			sb.append(" = {}");
+            			sb.append(ASEmitterTokens.SEMICOLON.getToken() + "\n");
+    	                current += ".";
+            		}
+            	}
+            	sb.append("\n\n");
+            	sb.append("/**\n");
+            	sb.append(" * @constructor\n");
+            	String baseString = cdef.getBaseClassAsDisplayString();
+            	if (baseString.length() > 0)
+            		sb.append(" * @extends {" + baseString + "}\n");
+            	String[] ifaces = cdef.getImplementedInterfacesAsDisplayStrings();
+            	for (String iface : ifaces)
+            		sb.append(" * @implements {" + iface + "}\n");
+            	sb.append(" */\n");
+            	if (pkgName.length() == 0)
+                    sb.append("function " + cdef.getQualifiedName() + "() {}\n");
+            	else
+            		sb.append(cdef.getQualifiedName() + " = function() {}\n");
+                
+            	ASScope cscope = cdef.getContainedScope();
+            	Collection<IDefinitionSet> defSets = cscope.getAllLocalDefinitionSets();
+            	IDefinitionSet[] arrayOfDefSets = new IDefinitionSet[defSets.size()];
+            	defSets.toArray(arrayOfDefSets);
+            	for (IDefinitionSet defSet : arrayOfDefSets)
+            	{
+            		int n = defSet.getSize();
+            		for (int i = 0; i < n; i++)
+            		{
+            			IDefinition api = defSet.getDefinition(i);
+            			String apiName = api.getBaseName();
+            			if (apiName.startsWith("#")) continue; // invalid in externs
+            			if (!api.isOverride() && (api.isProtected() || api.isPublic()))
+            			{
+            				if (!(api instanceof FunctionDefinition) ||
+            						api instanceof AccessorDefinition)
+            				{
+                            	sb.append("\n\n");
+                            	sb.append("/**\n");
+                            	sb.append(" * @type {" + getJSType(api.getTypeAsDisplayString()) + "}\n");
+                            	sb.append(" */\n");
+                            	sb.append(cdef.getQualifiedName() + ".");
+                            	if (!api.isStatic())
+                            		sb.append("prototype.");
+                            	sb.append(api.getBaseName() + ";\n");            					
+            				}
+            				else
+            				{
+            					FunctionDefinition method = (FunctionDefinition)api;
+            					ParameterDefinition[] params = method.getParameters();
+                            	sb.append("\n\n");
+                            	sb.append("/**\n");
+                            	for (ParameterDefinition param : params)
+                            	{
+                            		if (param.getBaseName().isEmpty())
+                            			sb.append(" * @param {*=} opt_rest\n");
+                            		else
+                            			sb.append(" * @param {" + getJSType(param.getTypeAsDisplayString()) + "} " + param.getBaseName() + "\n");
+                            	}
+                            	String ret = getJSType(method.getReturnTypeAsDisplayString());
+                            	if (!ret.equals("void"))
+                            		sb.append(" * @returns {" + ret + "}\n");
+                            	sb.append(" */\n");
+                            	sb.append(cdef.getQualifiedName() + ".");
+                            	if (!api.isStatic())
+                            		sb.append("prototype.");
+                            	sb.append(api.getBaseName());
+                            	sb.append(" = function(");
+                            	int m = params.length;
+                            	for (int j = 0; j < m; j++)
+                            	{
+                            		if (j > 0)
+                            			sb.append(",");
+                            		if (params[j].getBaseName().isEmpty())
+                            			sb.append("opt_rest");
+                            		else
+                            			sb.append(params[j].getBaseName());
+                            	}
+                            	sb.append(") {");
+                            	if (!ret.equals("void"))
+                            	{
+                            		if (ret.equals("number"))
+                            			sb.append(" return 0; ");
+                            		else if (ret.equals("boolean"))
+                            			sb.append(" return false; ");
+                            		else
+                            			sb.append(" return null; ");
+                            	}
+                            	sb.append("};\n");
+            				}
+            			}
+            		}
+            	}            	
+            }
+            else if (actualDef instanceof InterfaceDefinition)
+            {
+            	sb.append("\n\n");
+            	InterfaceDefinition cdef = (InterfaceDefinition)actualDef;
+            	String pkgName = cdef.getPackageName();
+            	if (pkgName.length() > 0 && !packageNames.contains(pkgName))
+            	{
+            		packageNames.add(pkgName);
+            		String[] parts = pkgName.split("\\.");
+            		String current = "";
+            		boolean firstOne = true;
+            		for (String part : parts)
+            		{
+            			current += part;
+            			if (partNames.contains(current))
+            			{
+            				firstOne = false;
+        	                current += ".";
+            				continue;
+            			}            			
+            			partNames.add(current);
+        				sb.append("/**\n * @suppress {duplicate}\n * @const\n */\n");
+            			if (firstOne)
+            			{
+            				sb.append("var ");
+            				firstOne = false;
+            			}
+            			sb.append(current);
+            			sb.append(" = {}");
+            			sb.append(ASEmitterTokens.SEMICOLON.getToken() + "\n");
+    	                current += ".";
+            		}
+            	}
+            	sb.append("\n\n");
+            	sb.append("/**\n");
+            	sb.append(" * @interface\n");
+            	String[] ifaces = cdef.getExtendedInterfacesAsDisplayStrings();
+            	for (String iface : ifaces)
+            		sb.append(" * @extends {" + iface + "}\n");
+            	sb.append(" */\n");
+                sb.append(cdef.getQualifiedName() + " = function() {}\n");
+            }
+        }
+        if (config.isVerbose())
+        {
+            System.out.println("Writing externs report: " + externsReportFile.getAbsolutePath());
+        }
+        FileWriter fw;
+		try {
+			fw = new FileWriter(externsReportFile, false);
+            fw.write(sb.toString());
+            fw.close();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+    
+    private String getJSType(String s)
+    {
+    	if (s.contains("__AS3__.vec.Vector"))
+    		return "Array";
+    	return JSGoogDocEmitter.convertASTypeToJSType(s, "");
+    }
+
+	private void outputResourceBundle(ResourceBundleCompilationUnit cu, File outputFolder) {
 		// TODO Auto-generated method stub
         final ISWCManager swcManager = project.getWorkspace().getSWCManager();
         // find the SWC
         final ISWC swc = swcManager.get(new File(cu.getAbsoluteFilename()));
         if (swc != null)
         {
-        	String bundleName = cu.getBundleNameInColonSyntax();
-        	String propFileName = "locale/" + cu.getLocale() + "/" + bundleName + ".properties";
-        	String bundleClassName = cu.getLocale() + "$" + bundleName + "_properties";
-            Map<String, ISWCFileEntry> files = swc.getFiles();
-            for (String key : files.keySet())
+            if (swc.getSWCFile().getAbsolutePath().endsWith(".swc"))
             {
-                if (key.equals(propFileName))
-                {
-                	if (!project.compiledResourceBundleNames.contains(bundleName))
-                		project.compiledResourceBundleNames.add(bundleName);
-                	project.compiledResourceBundleClasses.add(bundleClassName);
-                	StringBuilder sb = new StringBuilder();
-                    ISWCFileEntry fileEntry = swc.getFile(key);
-                    if (fileEntry != null)
-                    {
-                        try {
-							InputStream is = fileEntry.createInputStream();
-							BufferedReader br = new BufferedReader(new InputStreamReader(is));
-							String line;
-							while ((line = br.readLine()) != null)
-							{
-								if (line.contains("="))
-								{
-									if (sb.length() == 0)
-									{
-										sb.append("/**\n");
-										sb.append(" * Generated by Apache Royale Compiler from " + bundleClassName + ".properties\n");
-										sb.append(" * " + bundleClassName + "\n");
-										sb.append(" *\n");
-										sb.append(" * @fileoverview\n");
-										sb.append(" *\n");
-										sb.append(" * @suppress {checkTypes|accessControls}\n");
-										sb.append(" */\n\n");
-										sb.append("goog.provide('" + bundleClassName + "');\n\n");
-										sb.append("goog.require('mx.resources.IResourceBundle');\n");
-										sb.append("goog.require('mx.resources.ResourceBundle');\n\n\n");
-										sb.append("/**\n");
-										sb.append(" * @constructor\n");
-										sb.append(" * @extends {mx.resources.ResourceBundle}\n");
-										sb.append(" * @implements {mx.resources.IResourceBundle}\n");
-										sb.append(" */\n");
-										sb.append(bundleClassName + " = function() {\n");
-										sb.append("    " + bundleClassName + ".base(this, 'constructor');\n");
-										sb.append("};\n");
-										sb.append("goog.inherits(" + bundleClassName + ", mx.resources.ResourceBundle);\n\n");
-										sb.append("/**\n");
-										sb.append(" * Prevent renaming of class. Needed for reflection.\n");
-										sb.append(" */\n");
-										sb.append("goog.exportSymbol('" + bundleClassName + "', " + bundleClassName + ");\n\n");
-										sb.append(bundleClassName + ".prototype.getContent = function() { return {\n");
-									}
-									int c = line.indexOf("=");
-									String propName = line.substring(0, c);
-									String value = line.substring(c + 1);
-									while (value.endsWith("/"))
-									{
-										value = value.substring(0, value.length() - 1);
-										value += br.readLine();
-									}
-									sb.append(propName + ": \"" + value + "\",\n");
-								}
+	        	String bundleName = cu.getBundleNameInColonSyntax();
+	        	String propFileName = "locale/" + cu.getLocale() + "/" + bundleName + ".properties";
+	        	String bundleClassName = cu.getLocale() + "$" + bundleName + "_properties";
+	            Map<String, ISWCFileEntry> files = swc.getFiles();
+	            for (String key : files.keySet())
+	            {
+	                if (key.equals(propFileName))
+	                {
+	                	if (!project.compiledResourceBundleNames.contains(bundleName))
+	                		project.compiledResourceBundleNames.add(bundleName);
+	                	project.compiledResourceBundleClasses.add(bundleClassName);
+	                    ISWCFileEntry fileEntry = swc.getFile(key);
+	                    if (fileEntry != null)
+	                    {
+							InputStream is;
+							try {
+								is = fileEntry.createInputStream();
+								BufferedReader br = new BufferedReader(new InputStreamReader(is));
+			                	writeResourceBundle(br, bundleClassName, outputFolder);
+							} catch (IOException e) {
+								// TODO Auto-generated catch block
+								e.printStackTrace();
 							}
-							sb.append("__end_of_bundle__: 0\n};};\n");
-						} catch (IOException e) {
-							// TODO Auto-generated catch block
-							e.printStackTrace();
-						}
-                    }
-                    final File outputClassFile = getOutputClassFile(
-                            bundleClassName, outputFolder);
-                    System.out.println("Generating resource file: " + outputClassFile);
-                    FileWriter fw;
-					try {
-						fw = new FileWriter(outputClassFile, false);
-	                    fw.write(sb.toString());
-	                    fw.close();
-					} catch (IOException e) {
-						// TODO Auto-generated catch block
-						e.printStackTrace();
-					}
-                }
+	                    }
+	                }
+	            }
+            }
+            else
+            {
+            	// it isn't a bundle from a SWC, it is a bundle in the source path
+	        	String bundleName = cu.getBundleNameInColonSyntax();
+	        	String bundleClassName = cu.getLocale() + "$" + bundleName + "_properties";
+            	if (!project.compiledResourceBundleNames.contains(bundleName))
+            		project.compiledResourceBundleNames.add(bundleName);
+            	project.compiledResourceBundleClasses.add(bundleClassName);
+				InputStream is;
+				try {
+					is = new FileInputStream(swc.getSWCFile());
+					BufferedReader br = new BufferedReader(new InputStreamReader(is));
+                	writeResourceBundle(br, bundleClassName, outputFolder);
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
             }
         }
-
 	}
 
+	private void writeResourceBundle(BufferedReader br, String bundleClassName, File outputFolder)
+	{
+		StringBuilder sb = new StringBuilder();
+		try {
+			String line;
+			while ((line = br.readLine()) != null)
+			{
+				if (line.contains("="))
+				{
+					if (sb.length() == 0)
+					{
+						sb.append("/**\n");
+						sb.append(" * Generated by Apache Royale Compiler from " + bundleClassName + ".properties\n");
+						sb.append(" * " + bundleClassName + "\n");
+						sb.append(" *\n");
+						sb.append(" * @fileoverview\n");
+						sb.append(" *\n");
+						sb.append(" * @suppress {checkTypes|accessControls}\n");
+						sb.append(" */\n\n");
+						sb.append("goog.provide('" + bundleClassName + "');\n\n");
+						sb.append("goog.require('mx.resources.IResourceBundle');\n");
+						sb.append("goog.require('mx.resources.ResourceBundle');\n\n\n");
+						sb.append("/**\n");
+						sb.append(" * @constructor\n");
+						sb.append(" * @extends {mx.resources.ResourceBundle}\n");
+						sb.append(" * @implements {mx.resources.IResourceBundle}\n");
+						sb.append(" */\n");
+						sb.append(bundleClassName + " = function() {\n");
+						sb.append("    " + bundleClassName + ".base(this, 'constructor');\n");
+						sb.append("};\n");
+						sb.append("goog.inherits(" + bundleClassName + ", mx.resources.ResourceBundle);\n\n");
+						sb.append("/**\n");
+						sb.append(" * Prevent renaming of class. Needed for reflection.\n");
+						sb.append(" */\n");
+						sb.append("goog.exportSymbol('" + bundleClassName + "', " + bundleClassName + ");\n\n");
+						sb.append(bundleClassName + ".prototype.getContent = function() { return {\n");
+					}
+					int c = line.indexOf("=");
+					String propName = line.substring(0, c);
+					String value = line.substring(c + 1);
+					while (value.endsWith("/"))
+					{
+						value = value.substring(0, value.length() - 1);
+						value += br.readLine();
+					}
+					sb.append(propName + ": \"" + value + "\",\n");
+				}
+			}
+			sb.append("__end_of_bundle__: 0\n};};\n");
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		final File outputClassFile = getOutputClassFile(
+                bundleClassName, outputFolder);
+        if (config.isVerbose())
+        {
+            System.out.println("Generating resource file: " + outputClassFile);
+        }
+		FileWriter fw;
+		try {
+			fw = new FileWriter(outputClassFile, false);
+			fw.write(sb.toString());
+			fw.close();
+			long fileDate = 0;
+        	String metadataDate = targetSettings.getSWFMetadataDate();
+        	if (metadataDate != null)
+        	{
+        		String metadataFormat = targetSettings.getSWFMetadataDateFormat();
+        		try {
+        			SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
+        			fileDate = sdf.parse(metadataDate).getTime();
+        		} catch (ParseException e) {
+    				// TODO Auto-generated catch block
+    				e.printStackTrace();
+    			} catch (IllegalArgumentException e1) {
+    				e1.printStackTrace();
+    			}
+        		outputClassFile.setLastModified(fileDate);
+        	}
+
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+	}
+	
 	/**
      * Build target artifact.
      * 
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCRoyaleCordova.java b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCRoyaleCordova.java
index 6e91ea0..378339c 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCRoyaleCordova.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCRoyaleCordova.java
@@ -49,6 +49,7 @@
 import org.apache.royale.compiler.exceptions.ConfigurationException.MustSpecifyTarget;
 import org.apache.royale.compiler.exceptions.ConfigurationException.OnlyOneSource;
 import org.apache.royale.compiler.internal.config.FlashBuilderConfigurator;
+import org.apache.royale.compiler.internal.definitions.DefinitionBase;
 import org.apache.royale.compiler.internal.driver.js.goog.JSGoogConfiguration;
 import org.apache.royale.compiler.internal.driver.mxml.royale.MXMLRoyaleCordovaBackend;
 import org.apache.royale.compiler.internal.parsing.as.RoyaleASDocDelegate;
@@ -99,7 +100,7 @@
     {
         SUCCESS(0),
         PRINT_HELP(1),
-        FAILED_WITH_PROBLEMS(2),
+        FAILED_WITH_PROBLEMS(0),
         FAILED_WITH_ERRORS(3),
         FAILED_WITH_EXCEPTIONS(4),
         FAILED_WITH_CONFIG_PROBLEMS(5);
@@ -179,6 +180,7 @@
     
     public MXMLJSCRoyaleCordova(IBackend backend)
     {
+        DefinitionBase.setPerformanceCachingEnabled(true);
         workspace = new Workspace();
         workspace.setASDocDelegate(new RoyaleASDocDelegate());
         project = new RoyaleJSProject(workspace, backend);
@@ -342,7 +344,10 @@
 	                        final File outputClassFile = getOutputClassFile(
 	                                cu.getQualifiedNames().get(0), outputFolder);
 	
-	                        System.out.println("Compiling file: " + outputClassFile);
+                            if (config.isVerbose())
+                            {
+                                System.out.println("Compiling file: " + outputClassFile);
+                            }
 	
 	                        ICompilationUnit unit = cu;
 	
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/IJSEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/IJSEmitter.java
index 5dffb4d..b68f9f0 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/IJSEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/IJSEmitter.java
@@ -25,6 +25,7 @@
 import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.internal.codegen.js.JSSessionModel;
 import org.apache.royale.compiler.tree.as.IASNode;
+import org.apache.royale.compiler.tree.as.IExpressionNode;
 import org.apache.royale.compiler.tree.as.ITypeNode;
 import org.apache.royale.compiler.visitor.IASNodeStrategy;
 
@@ -45,4 +46,6 @@
     
     void emitClosureStart();
     void emitClosureEnd(IASNode node, IDefinition nodeDef);
+
+    void emitAssignmentCoercion(IExpressionNode assignedNode, IDefinition definition);
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/goog/IJSGoogDocEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/goog/IJSGoogDocEmitter.java
index 112f3a0..6c99459 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/goog/IJSGoogDocEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/goog/IJSGoogDocEmitter.java
@@ -134,7 +134,7 @@
 
     void emitThis(ITypeDefinition node, String packageName);
 
-    void emitType(IASNode node, String packageName);
+    void emitType(IASNode node, String packageName, ICompilerProject project);
 
 	void emitType(String type, String packageName);
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/as/ASEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/as/ASEmitter.java
index f80c674..d04b4ee 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/as/ASEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/as/ASEmitter.java
@@ -864,6 +864,18 @@
     public void emitMethodScope(IScopedNode node)
     {
         write(ASEmitterTokens.SPACE);
+        if (node instanceof IContainerNode)
+        {
+            IContainerNode container = (IContainerNode) node;
+            //native or abstract methods may have a synthesized scope block
+            if (container.getContainerType().equals(ContainerType.SYNTHESIZED))
+            {
+                write(ASEmitterTokens.BLOCK_OPEN);
+                writeNewline();
+                write(ASEmitterTokens.BLOCK_CLOSE);
+                return;
+            }
+        }
         getWalker().walk(node);
     }
 
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/as/ASWriter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/as/ASWriter.java
index 1384a9d..62ef771 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/as/ASWriter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/as/ASWriter.java
@@ -77,7 +77,7 @@
 
         try
         {
-            out.write(writer.toString().getBytes());
+            out.write(writer.toString().getBytes("utf8"));
         }
         catch (IOException e)
         {
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSDocEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSDocEmitter.java
index de44564..8840e5b 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSDocEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSDocEmitter.java
@@ -29,7 +29,8 @@
 public class JSDocEmitter implements IDocEmitter, IEmitter
 {
 
-    private int currentIndent = 0;
+    @SuppressWarnings("unused")
+	private int currentIndent = 0;
 
     protected IEmitter emitter;
 
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java
index ae8768a..d6a9745 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java
@@ -23,12 +23,21 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.royale.compiler.codegen.IASGlobalFunctionConstants;
+import org.apache.royale.compiler.codegen.IDocEmitter;
 import org.apache.royale.compiler.codegen.IEmitter;
 import org.apache.royale.compiler.codegen.ISubEmitter;
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
 import org.apache.royale.compiler.codegen.js.IMappingEmitter;
 import org.apache.royale.compiler.common.ISourceLocation;
+import org.apache.royale.compiler.constants.IASLanguageConstants;
+import org.apache.royale.compiler.constants.IMetaAttributeConstants;
+import org.apache.royale.compiler.constants.IASLanguageConstants.BuiltinType;
+import org.apache.royale.compiler.definitions.IAppliedVectorDefinition;
+import org.apache.royale.compiler.definitions.IClassDefinition;
 import org.apache.royale.compiler.definitions.IDefinition;
+import org.apache.royale.compiler.definitions.metadata.IMetaTag;
+import org.apache.royale.compiler.definitions.metadata.IMetaTagAttribute;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitter;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.jx.BlockCloseEmitter;
@@ -57,12 +66,18 @@
 import org.apache.royale.compiler.internal.codegen.js.jx.UnaryOperatorEmitter;
 import org.apache.royale.compiler.internal.codegen.js.jx.WhileLoopEmitter;
 import org.apache.royale.compiler.internal.codegen.js.jx.WithEmitter;
-import org.apache.royale.compiler.internal.tree.as.FunctionNode;
+import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleDocEmitter;
+import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens;
+import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
+import org.apache.royale.compiler.internal.semantics.SemanticUtils;
+import org.apache.royale.compiler.internal.tree.as.*;
+import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.as.IASNode;
 import org.apache.royale.compiler.tree.as.ICatchNode;
 import org.apache.royale.compiler.tree.as.IContainerNode;
 import org.apache.royale.compiler.tree.as.IDefinitionNode;
 import org.apache.royale.compiler.tree.as.IDynamicAccessNode;
+import org.apache.royale.compiler.tree.as.IExpressionNode;
 import org.apache.royale.compiler.tree.as.IForLoopNode;
 import org.apache.royale.compiler.tree.as.IFunctionNode;
 import org.apache.royale.compiler.tree.as.IFunctionObjectNode;
@@ -87,6 +102,9 @@
 
 import com.google.debugging.sourcemap.FilePosition;
 
+import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.royale.compiler.utils.NativeUtils;
+
 /**
  * @author Michael Schmalle
  */
@@ -196,6 +214,13 @@
         startMapping(node);
         FunctionNode fnode = node.getFunctionNode();
         write(ASEmitterTokens.FUNCTION);
+        String name = fnode.getName();
+        //may have a name, or may be anonymous
+        if(name.length() > 0)
+        {
+            write(ASEmitterTokens.SPACE);
+            write(name);
+        }
         endMapping(node);
         emitParameters(fnode.getParametersContainerNode());
         emitFunctionScope(fnode.getScopedNode());
@@ -203,16 +228,17 @@
 
     public void emitClosureStart()
     {
-    	
+    
     }
 
     public void emitClosureEnd(IASNode node, IDefinition nodeDef)
     {
-    	
+    
     }
     
     public void emitSourceMapDirective(ITypeNode node)
     {
+        sourceMapDirectiveEmitter.isExterns = getModel().isExterns;
         sourceMapDirectiveEmitter.emit(node);
     }
 
@@ -422,6 +448,9 @@
             }
         }
 
+        //prefer forward slash
+        sourcePath = sourcePath.replace('\\', '/');
+
         SourceMapMapping mapping = new SourceMapMapping();
         mapping.sourcePath = sourcePath;
         mapping.sourceStartPosition = new FilePosition(line, column);
@@ -481,7 +510,7 @@
     /**
      * Adjusts the line numbers saved in the source map when a line should be
      * removed during post processing.
-     * 
+     *
      * @param lineIndex
      */
     protected void removeLineFromMappings(int lineIndex)
@@ -505,4 +534,390 @@
 		return className.replace(".", "_") + "_" + name;
 	}
 
+    public void emitAssignmentCoercion(IExpressionNode assignedNode, IDefinition definition)
+    {
+        IDefinition assignedDef = null;
+        IDefinition assignedTypeDef = null;
+        ICompilerProject project = getWalker().getProject();
+        if (assignedNode != null)
+        {
+            assignedDef = assignedNode.resolve(project);
+            assignedTypeDef = assignedNode.resolveType(project);
+            if (project.getBuiltinType(BuiltinType.ANY_TYPE).equals(assignedTypeDef))
+            {
+                IDefinition resolvedXMLDef = SemanticUtils.resolveXML(assignedNode, project);
+                if (resolvedXMLDef != null)
+                {
+                    assignedDef = resolvedXMLDef;
+                    assignedTypeDef = SemanticUtils.resolveTypeXML(assignedNode, project);
+                }
+            }
+        }
+		String coercionStart = null;
+        String coercionEnd = null;
+        boolean avoidCoercion = false;
+		if (project.getBuiltinType(BuiltinType.INT).equals(definition))
+		{
+			boolean needsCoercion = false;
+			if (assignedNode instanceof INumericLiteralNode)
+			{
+				INumericLiteralNode numericLiteral = (INumericLiteralNode) assignedNode;
+                INumericLiteralNode.INumericValue numericValue = numericLiteral.getNumericValue();
+                startMapping(assignedNode);
+                if(numericValue.toString().startsWith("0x"))
+                {
+                    //for readability, keep the same formatting
+                    write("0x" + Integer.toHexString(numericValue.toInt32()));
+                }
+                else
+                {
+                    write(Integer.toString(numericValue.toInt32()));
+                }
+                endMapping(assignedNode);
+                return;
+			}
+			else if(assignedNode instanceof BinaryOperatorAsNode)
+            {
+                needsCoercion = true;
+            }
+			else if(!project.getBuiltinType(BuiltinType.INT).equals(assignedTypeDef))
+			{
+				needsCoercion = true;
+			}
+			if (needsCoercion)
+			{
+				coercionStart = "(";
+				coercionEnd = ") >> 0";
+			}
+		}
+		else if (project.getBuiltinType(BuiltinType.UINT).equals(definition))
+		{
+			boolean needsCoercion = false;
+			if (assignedNode instanceof INumericLiteralNode)
+			{
+                INumericLiteralNode numericLiteral = (INumericLiteralNode) assignedNode;
+                INumericLiteralNode.INumericValue numericValue = numericLiteral.getNumericValue();
+                startMapping(assignedNode);
+                if(numericValue.toString().startsWith("0x"))
+                {
+                    //for readability, keep the same formatting
+                    write("0x" + Long.toHexString(numericValue.toUint32()));
+                }
+                else
+                {
+                    write(Long.toString(numericValue.toUint32()));
+                }
+                endMapping(assignedNode);
+                return;
+			}
+            else if(assignedNode instanceof BinaryOperatorAsNode)
+            {
+                needsCoercion = true;
+            }
+			else if(!project.getBuiltinType(BuiltinType.UINT).equals(assignedTypeDef))
+			{
+				needsCoercion = true;
+			}
+			if (needsCoercion)
+			{
+				coercionStart = "(";
+				coercionEnd = ") >>> 0";
+            }
+        }
+        else if (project.getBuiltinType(BuiltinType.NUMBER).equals(definition)
+                && !project.getBuiltinType(BuiltinType.NUMBER).equals(assignedTypeDef)
+                && !project.getBuiltinType(BuiltinType.INT).equals(assignedTypeDef)
+                && !project.getBuiltinType(BuiltinType.UINT).equals(assignedTypeDef))
+        {
+			boolean needsCoercion = true;
+            if (assignedNode instanceof IDynamicAccessNode)
+            {
+                IDynamicAccessNode dynamicAccess = (IDynamicAccessNode) assignedNode;
+                IDefinition dynamicAccessIndexDef = dynamicAccess.getRightOperandNode().resolveType(project);
+                if (project.getBuiltinType(BuiltinType.NUMBER).equals(dynamicAccessIndexDef))
+                {
+                    IDefinition leftDef = dynamicAccess.getLeftOperandNode().resolveType(project);
+                    IMetaTag[] metas = leftDef.getAllMetaTags();
+                    for (IMetaTag meta : metas)
+                    {
+                        if (meta.getTagName().equals(IMetaAttributeConstants.ATTRIBUTE_ARRAYELEMENTTYPE))
+                        {
+                            IMetaTagAttribute[] attrs = meta.getAllAttributes();
+                            for (IMetaTagAttribute attr : attrs)
+                            {
+                                String t = attr.getValue();
+                                if (t.equals(IASLanguageConstants.Number))
+                                {
+                                    needsCoercion = false;
+                                    //explicitly prevent other coercion detection rules from picking this up
+                                    avoidCoercion = true;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            if (needsCoercion)
+            {
+                coercionStart = "Number(";
+            }
+        }
+        else if (project.getBuiltinType(BuiltinType.BOOLEAN).equals(definition)
+                && !project.getBuiltinType(BuiltinType.BOOLEAN).equals(assignedTypeDef))
+        {
+            if (project.getBuiltinType(BuiltinType.NULL).equals(assignedTypeDef)
+                    || (assignedDef != null && assignedDef.getQualifiedName().equals(IASLanguageConstants.UNDEFINED)))
+            {
+                //null and undefined are coerced to false
+                startMapping(assignedNode);
+                write(IASLanguageConstants.FALSE);
+                endMapping(assignedNode);
+                return;
+            }
+			if (assignedNode instanceof INumericLiteralNode)
+			{
+                INumericLiteralNode numericLiteral = (INumericLiteralNode) assignedNode;
+                INumericLiteralNode.INumericValue numericValue = numericLiteral.getNumericValue();
+                //zero is coerced to false, and everything else is true
+                String booleanValue = numericValue.toNumber() == 0.0
+                        ? IASLanguageConstants.FALSE
+                        : IASLanguageConstants.TRUE;
+                startMapping(assignedNode);
+                write(booleanValue);
+                endMapping(assignedNode);
+                return;
+			}
+            coercionStart = "!!(";
+        }
+        else if (project.getBuiltinType(BuiltinType.STRING).equals(definition)
+                && !project.getBuiltinType(BuiltinType.STRING).equals(assignedTypeDef)
+                && !project.getBuiltinType(BuiltinType.NULL).equals(assignedTypeDef)
+                && !(project.getBuiltinType(BuiltinType.ANY_TYPE).equals(assignedTypeDef)
+                        && SemanticUtils.isToStringFunctionCall(assignedNode, project)))
+        {
+            if(assignedDef != null && assignedDef.getQualifiedName().equals(IASLanguageConstants.UNDEFINED))
+            {
+                //undefined is coerced to null
+                startMapping(assignedNode);
+                write(IASLanguageConstants.NULL);
+                endMapping(assignedNode);
+                return;
+            }
+            boolean emitStringCoercion = true;
+            IDocEmitter docEmitter = getDocEmitter();
+            if (docEmitter instanceof JSRoyaleDocEmitter)
+            {
+                JSRoyaleDocEmitter royaleDocEmitter = (JSRoyaleDocEmitter) docEmitter;
+                emitStringCoercion = royaleDocEmitter.emitStringConversions;
+            }
+            if (emitStringCoercion)
+            {
+                coercionStart = "org.apache.royale.utils.Language.string(";
+            }
+        }
+        if ( assignedDef != null
+                && assignedDef instanceof IAppliedVectorDefinition
+                && assignedNode instanceof TypedExpressionNode) {
+            //assign a Vector class as the assigned value, e.g. var c:Class = Vector.<int>
+            if (project instanceof RoyaleJSProject
+                    && ((RoyaleJSProject)project).config.getJsVectorEmulationClass() != null) {
+                startMapping(assignedNode);
+                write(((RoyaleJSProject)project).config.getJsVectorEmulationClass());
+                endMapping(assignedNode);
+            } else {
+                startMapping(assignedNode);
+                write(JSRoyaleEmitterTokens.SYNTH_VECTOR);
+                write(ASEmitterTokens.PAREN_OPEN);
+                write(ASEmitterTokens.SINGLE_QUOTE);
+                //the element type of the Vector:
+                write(formatQualifiedName(((TypedExpressionNode)assignedNode).getTypeNode().resolve(project).getQualifiedName()));
+                write(ASEmitterTokens.SINGLE_QUOTE);
+                write(ASEmitterTokens.PAREN_CLOSE);
+                endMapping(assignedNode);
+                if (project instanceof RoyaleJSProject)
+                    ((RoyaleJSProject)project).needLanguage = true;
+                getModel().needLanguage = true;
+            }
+            return;
+        }
+        if (assignedDef instanceof IClassDefinition
+                && assignedNode instanceof IdentifierNode
+                && ((IdentifierNode)assignedNode).getName().equals(IASGlobalFunctionConstants.Vector)
+                && project instanceof RoyaleJSProject
+                && ((RoyaleJSProject)project).config.getJsVectorEmulationClass() == null   ){
+            startMapping(assignedNode);
+            write(JSRoyaleEmitterTokens.SYNTH_VECTOR);
+            write(ASEmitterTokens.PAREN_OPEN);
+            //null to signify not a valid constructor
+            write(ASEmitterTokens.NULL);
+            write(ASEmitterTokens.PAREN_CLOSE);
+            endMapping(assignedNode);
+            if (project instanceof RoyaleJSProject)
+                ((RoyaleJSProject)project).needLanguage = true;
+            getModel().needLanguage = true;
+            return;
+        }
+        if (coercionStart == null
+                && !avoidCoercion
+                && assignedTypeDef !=null
+                && definition !=null
+                && (project.getBuiltinType(BuiltinType.ANY_TYPE).equals(assignedTypeDef)
+                || project.getBuiltinType(BuiltinType.OBJECT).equals(assignedTypeDef))
+                && !(project.getBuiltinType(BuiltinType.ANY_TYPE).equals(definition)
+                        || project.getBuiltinType(BuiltinType.OBJECT).equals(definition))) {
+            //catch leftovers: remaining implicit coercion of loosely typed assigned values to strongly typed context
+            //assignment to Class definitions is excluded because there is no 'Class' type in JS
+            //Possibility: 'Class' could be implemented as a synthType
+            boolean needsCoercion = ((RoyaleJSProject)project).config.getJsComplexImplicitCoercions();
+    
+            IDocEmitter docEmitter = getDocEmitter();
+            if (docEmitter instanceof JSRoyaleDocEmitter)
+            {
+                JSRoyaleDocEmitter royaleDocEmitter = (JSRoyaleDocEmitter) docEmitter;
+                //check for local toggle
+                if (needsCoercion) needsCoercion = !(royaleDocEmitter.getLocalSettingAsBoolean(
+                        JSRoyaleEmitterTokens.SUPPRESS_COMPLEX_IMPLICIT_COERCION, false));
+                else {
+                    if (royaleDocEmitter.hasLocalSetting(JSRoyaleEmitterTokens.SUPPRESS_COMPLEX_IMPLICIT_COERCION.getToken())) {
+                        needsCoercion = !(royaleDocEmitter.getLocalSettingAsBoolean(
+                                JSRoyaleEmitterTokens.SUPPRESS_COMPLEX_IMPLICIT_COERCION, false));
+                    }
+                }
+                if (needsCoercion) {
+                    //check for individual specified suppression
+                    
+                    String definitionName = definition.getQualifiedName();
+                    //for Vectors, use the unqualified name to match the source code
+                    if (NativeUtils.isVector(definitionName)) {
+                        definitionName = definition.getBaseName();
+                    }
+                    
+                    if (royaleDocEmitter.getLocalSettingIncludesString(
+                            JSRoyaleEmitterTokens.SUPPRESS_COMPLEX_IMPLICIT_COERCION,
+                            definitionName))
+                    {
+                        needsCoercion = false;
+                    }
+                    
+                }
+            }
+            
+            //Avoid specific compile-time 'fake' class(es)
+            if (needsCoercion && definition.getQualifiedName().equals("org.apache.royale.core.WrappedHTMLElement")) {
+                //*actual* coercion fails here, because this is not actually instantiated, it is
+                //simply a type definition representing the 'wrapped' (or tagged) HTMLElement
+                needsCoercion = false;
+            }
+            
+            //Avoid XML/XMLList:
+            if (needsCoercion && project.getBuiltinType(BuiltinType.XML) != null) {
+                if (project.getBuiltinType(BuiltinType.XML).equals(definition)
+                        || project.getBuiltinType(BuiltinType.XMLLIST).equals(definition)) {
+                    //XML/XMLList has complex output and would need more work
+                    needsCoercion = false;
+                }
+            }
+            
+            //avoid scenario with ArrayElementType specified as metadata definition type - assume it is 'typed'
+            if (needsCoercion && assignedNode instanceof IDynamicAccessNode)
+            {
+                IDynamicAccessNode dynamicAccess = (IDynamicAccessNode) assignedNode;
+                IDefinition dynamicAccessIndexDef = dynamicAccess.getRightOperandNode().resolveType(project);
+                if (project.getBuiltinType(BuiltinType.NUMBER).equals(dynamicAccessIndexDef))
+                {
+                    IDefinition leftDef = dynamicAccess.getLeftOperandNode().resolveType(project);
+                    if (leftDef != null) {
+                        IMetaTag[] metas = leftDef.getAllMetaTags();
+                        for (IMetaTag meta : metas)
+                        {
+                            if (meta.getTagName().equals(IMetaAttributeConstants.ATTRIBUTE_ARRAYELEMENTTYPE))
+                            {
+                                IMetaTagAttribute[] attrs = meta.getAllAttributes();
+                                for (IMetaTagAttribute attr : attrs)
+                                {
+                                    String t = attr.getValue();
+                                    if (t.equals(definition.getQualifiedName()))
+                                    {
+                                        needsCoercion = false;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            if (needsCoercion && project.getBuiltinType(BuiltinType.STRING).equals(definition)) {
+                //explicit suppression of String coercion
+                if (docEmitter instanceof JSRoyaleDocEmitter)
+                {
+                    JSRoyaleDocEmitter royaleDocEmitter = (JSRoyaleDocEmitter) docEmitter;
+                    needsCoercion = royaleDocEmitter.emitStringConversions;
+                }
+                if (needsCoercion
+                        && assignedNode instanceof FunctionCallNode
+                        && ((FunctionCallNode) assignedNode).getNameNode() instanceof MemberAccessExpressionNode
+                        && ((MemberAccessExpressionNode)((FunctionCallNode) assignedNode).getNameNode()).getRightOperandNode()  instanceof IdentifierNode
+                        && ((IdentifierNode)(((MemberAccessExpressionNode)((FunctionCallNode) assignedNode).getNameNode()).getRightOperandNode())).getName().equals("toString")) {
+                        //even if toString() is called in an untyped way, assume a call to a method named 'toString' is actually providing a String
+                    needsCoercion = false;
+                }
+            }
+            
+            if (needsCoercion) {
+                //add a comment tag leader, so implicit casts are identifiable in the output
+                coercionStart = "/* implicit cast */ "
+                        + JSRoyaleEmitterTokens.LANGUAGE_QNAME.getToken()
+                        + ASEmitterTokens.MEMBER_ACCESS.getToken()
+                        + ASEmitterTokens.AS.getToken()
+                        + ASEmitterTokens.PAREN_OPEN.getToken();
+                String coercionTypeString = formatQualifiedName(definition.getQualifiedName());
+                if (NativeUtils.isSyntheticJSType(coercionTypeString)) {
+                    String synthCall;
+                    String synthethicType;
+                    if (NativeUtils.isVector(coercionTypeString)) {
+                        synthCall = JSRoyaleEmitterTokens.SYNTH_VECTOR.getToken();
+                        synthethicType = formatQualifiedName(coercionTypeString.substring(8, coercionTypeString.length() -1));
+                    } else {
+                        synthCall = JSRoyaleEmitterTokens.SYNTH_TYPE.getToken();
+                        synthethicType = coercionTypeString;
+                    }
+                    coercionTypeString = synthCall
+                            + ASEmitterTokens.PAREN_OPEN.getToken()
+                            + ASEmitterTokens.SINGLE_QUOTE.getToken()
+                            + synthethicType
+                            + ASEmitterTokens.SINGLE_QUOTE.getToken()
+                            + ASEmitterTokens.PAREN_CLOSE.getToken();
+                }
+                
+                coercionEnd = ASEmitterTokens.COMMA.getToken()
+                        + ASEmitterTokens.SPACE.getToken()
+                        + coercionTypeString
+                        + ASEmitterTokens.COMMA.getToken()
+                        + ASEmitterTokens.SPACE.getToken()
+                        + ASEmitterTokens.TRUE.getToken()
+                        + ASEmitterTokens.PAREN_CLOSE.getToken();
+                if (project instanceof RoyaleJSProject)
+                    ((RoyaleJSProject)project).needLanguage = true;
+                getModel().needLanguage = true;
+            }
+        }
+
+		if (coercionStart != null)
+		{
+			write(coercionStart);
+        }
+        emitAssignedValue(assignedNode);
+		if (coercionStart != null)
+		{
+			if (coercionEnd != null)
+			{
+				write(coercionEnd);
+			}
+			else
+			{
+				write(")");
+			}
+		}
+    }
+
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSSessionModel.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSSessionModel.java
index 6d24b66..55eb732 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSSessionModel.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSSessionModel.java
@@ -76,7 +76,14 @@
         public ArrayList<IFunctionNode> methods;
         public IClassDefinition classDefinition;
         public ImplicitBindableImplementation bindableImplementation;
+        public Boolean suppressExports;
     }
+    
+    public JSSessionModel()
+    {
+    	
+    }
+    
     private Stack<Context> stack = new Stack<Context>();
 
     public boolean needLanguage = false;
@@ -87,6 +94,8 @@
 
     public boolean inStaticInitializer = false;
     
+    public boolean suppressExports = false;
+    
     private LinkedHashMap<String, PropertyNodes> propertyMap = new LinkedHashMap<String, PropertyNodes>();
 
     private List<String> interfacePropertyMap = new ArrayList<String>();
@@ -107,6 +116,8 @@
 
     private ImplicitBindableImplementation implicitBindableImplementation = ImplicitBindableImplementation.NONE;
 
+    public String primaryDefinitionQName;
+    
     public IClassDefinition getCurrentClass()
     {
         return currentClass;
@@ -142,7 +153,9 @@
         context.vars = vars;
         context.methods = methods;
         context.bindableImplementation = implicitBindableImplementation;
+        context.suppressExports = suppressExports;
         stack.push(context);
+        suppressExports = false; //always defaults to false
         this.currentClass = currentClass;
         bindableVars = new HashMap<String, BindableVarInfo>();
         staticPropertyMap = new LinkedHashMap<String, PropertyNodes>();
@@ -166,6 +179,7 @@
         vars = context.vars;
         methods = context.methods;
         implicitBindableImplementation = context.bindableImplementation;
+        suppressExports = context.suppressExports;
     }
 
     public HashMap<String, PropertyNodes> getPropertyMap()
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSWriter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSWriter.java
index 50b0be2..376bcba 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSWriter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSWriter.java
@@ -99,7 +99,13 @@
         
         try
         {
-            jsOut.write(emitter.postProcess(writer.toString()).getBytes());
+            String emitted = writer.toString();
+            if(!isExterns)
+            {
+                //nothing to post-process in externs
+                emitted = emitter.postProcess(emitted);
+            }
+            jsOut.write(emitted.getBytes("utf8"));
         }
         catch (IOException e)
         {
@@ -109,11 +115,19 @@
         if (jsSourceMapOut != null)
         {
             String sourceMapFilePath = null;
+            String sourceRoot = null;
             if (sourceMapFile != null)
             {
                 sourceMapFilePath = sourceMapFile.getAbsolutePath();
                 convertMappingSourcePathsToRelative(emitter, sourceMapFile);
             }
+            else
+            {
+                sourceRoot = System.getProperty("user.dir");
+                convertMappingSourcePathsToRelative((IMappingEmitter) emitter, new File(sourceRoot, "test.js.map"));
+                sourceRoot = convertSourcePathToURI(sourceRoot);
+            }
+            convertMappingSourcePathsToURI(emitter);
 
             File compilationUnitFile = new File(compilationUnit.getAbsoluteFilename());
             ISourceMapEmitter sourceMapEmitter = backend.createSourceMapEmitter(emitter);
@@ -121,8 +135,8 @@
             {
                 String fileName = compilationUnitFile.getName();
                 fileName = fileName.replace(".as", ".js");
-                String sourceMap = sourceMapEmitter.emitSourceMap(fileName, sourceMapFilePath, null);
-                jsSourceMapOut.write(sourceMap.getBytes());
+                String sourceMap = sourceMapEmitter.emitSourceMap(fileName, sourceMapFilePath, sourceRoot);
+                jsSourceMapOut.write(sourceMap.getBytes("utf8"));
             } catch (Exception e)
             {
                 e.printStackTrace();
@@ -135,13 +149,36 @@
         List<IMappingEmitter.SourceMapMapping> mappings = emitter.getSourceMapMappings();
         for (IMappingEmitter.SourceMapMapping mapping : mappings)
         {
-            mapping.sourcePath = relativePath(mapping.sourcePath, relativeToFile.getAbsolutePath());
+            String relativePath = relativize(mapping.sourcePath, relativeToFile.getAbsolutePath());
+            mapping.sourcePath = relativePath;
         }
     }
+    
+    protected void convertMappingSourcePathsToURI(IMappingEmitter emitter)
+    {
+        List<IMappingEmitter.SourceMapMapping> mappings = emitter.getSourceMapMappings();
+        for (IMappingEmitter.SourceMapMapping mapping : mappings)
+        {
+            //prefer forward slash because web browser devtools expect it
+            String sourcePath = mapping.sourcePath;
+            sourcePath = convertSourcePathToURI(sourcePath);
+            mapping.sourcePath = sourcePath;
+        }
+    }
+    
+    protected String convertSourcePathToURI(String sourcePath)
+    {
+        File file = new File(sourcePath);
+        if(file.isAbsolute())
+        {
+            sourcePath = "file:///" + sourcePath;
+        }
+        return sourcePath.replace('\\', '/');
+    }
 
     //if we ever support Java 7, the java.nio.file.Path relativize() method
     //should be able to replace this method
-    private String relativePath(String filePath, String relativeToFilePath)
+    private String relativize(String filePath, String relativeToFilePath)
     {
         boolean caseInsensitive = System.getProperty("os.name").toLowerCase().startsWith("windows");
         if(caseInsensitive)
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JSGoogDocEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JSGoogDocEmitter.java
index 6c94259..c64823a 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JSGoogDocEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JSGoogDocEmitter.java
@@ -39,6 +39,7 @@
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter;
 import org.apache.royale.compiler.internal.scopes.ASScope;
 import org.apache.royale.compiler.internal.semantics.SemanticUtils;
+import org.apache.royale.compiler.internal.tree.as.TypedExpressionNode;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.as.IASNode;
 import org.apache.royale.compiler.tree.as.IClassNode;
@@ -128,7 +129,7 @@
         if (def != null)
             packageName = def.getPackageName();
 
-        emitType(node, packageName);
+        emitType(node, packageName, project);
 
         end();
     }
@@ -257,15 +258,14 @@
                     packageName = ((ITypeDefinition) type).getPackageName();
                 }
             }
-
-            emitTypeShort(node, project.getActualPackageName(packageName));
+            emitTypeShort(node, project.getActualPackageName(packageName), project);
         }
         else
         {
             writeNewline();
             begin();
             emitConst(node);
-            emitType(node, project.getActualPackageName(packageName));
+            emitType(node, project.getActualPackageName(packageName), project);
             end();
         }
     }
@@ -361,9 +361,18 @@
     }
 
     @Override
-    public void emitType(IASNode node, String packageName)
+    public void emitType(IASNode node, String packageName, ICompilerProject project)
     {
         String type = ((IVariableNode) node).getVariableType();
+        if (((IVariableNode) node).getVariableTypeNode() instanceof TypedExpressionNode) {
+            ITypeDefinition elemenTypeDef = ((TypedExpressionNode)(((IVariableNode) node).getVariableTypeNode())).getTypeNode().resolveType(project);
+            if (elemenTypeDef != null) {
+                type = "Vector.<" +
+                        convertASTypeToJS(elemenTypeDef.getQualifiedName(),"")
+                        +">";
+                packageName = "";
+            }
+        }
         emitJSDocLine(JSGoogDocEmitterTokens.TYPE.getToken(),
                 convertASTypeToJS(type, packageName));
     }
@@ -375,9 +384,18 @@
                 convertASTypeToJS(type, packageName));
     }
 
-    public void emitTypeShort(IASNode node, String packageName)
+    public void emitTypeShort(IASNode node, String packageName, ICompilerProject project)
     {
         String type = ((IVariableNode) node).getVariableType();
+        if (((IVariableNode) node).getVariableTypeNode() instanceof TypedExpressionNode) {
+            ITypeDefinition elemenTypeDef = ((TypedExpressionNode)(((IVariableNode) node).getVariableTypeNode())).getTypeNode().resolveType(project);
+            if (elemenTypeDef != null) {
+                type = "Vector.<" +
+                        convertASTypeToJS(elemenTypeDef.getQualifiedName(),"")
+                        +">";
+                packageName = "";
+            }
+        }
         writeToken(JSDocEmitterTokens.JSDOC_OPEN);
         write(ASEmitterTokens.ATSIGN);
         writeToken(JSGoogDocEmitterTokens.TYPE);
@@ -494,16 +512,18 @@
         	// is a vector so convert the element type
         	String elementType = name.substring(8, name.length() - 1);
         	elementType = convertASTypeToJSType(elementType, pname);
-        	name = "Vector.<" + elementType + ">";
+        	name = "Array.<" + elementType + ">";
         }
-        IASGlobalFunctionConstants.BuiltinType[] builtinTypes = IASGlobalFunctionConstants.BuiltinType
-                .values();
-        for (IASGlobalFunctionConstants.BuiltinType builtinType : builtinTypes)
-        {
-            if (name.equalsIgnoreCase(builtinType.getName()))
+        else {
+            IASGlobalFunctionConstants.BuiltinType[] builtinTypes = IASGlobalFunctionConstants.BuiltinType
+                    .values();
+            for (IASGlobalFunctionConstants.BuiltinType builtinType : builtinTypes)
             {
-                isBuiltinFunction = true;
-                break;
+                if (name.equalsIgnoreCase(builtinType.getName()))
+                {
+                    isBuiltinFunction = true;
+                    break;
+                }
             }
         }
 
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JSGoogEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JSGoogEmitter.java
index 88628d5..0d495f7 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JSGoogEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JSGoogEmitter.java
@@ -44,17 +44,13 @@
 import org.apache.royale.compiler.internal.codegen.js.JSEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSSessionModel;
 import org.apache.royale.compiler.internal.codegen.js.utils.EmitterUtils;
-import org.apache.royale.compiler.internal.definitions.AccessorDefinition;
 import org.apache.royale.compiler.internal.definitions.ClassDefinition;
-import org.apache.royale.compiler.internal.definitions.FunctionDefinition;
 import org.apache.royale.compiler.internal.definitions.NamespaceDefinition.INamepaceDeclarationDirective;
 import org.apache.royale.compiler.internal.definitions.VariableDefinition;
 import org.apache.royale.compiler.internal.scopes.PackageScope;
 import org.apache.royale.compiler.internal.tree.as.ChainedVariableNode;
 import org.apache.royale.compiler.internal.tree.as.FunctionCallNode;
 import org.apache.royale.compiler.internal.tree.as.FunctionNode;
-import org.apache.royale.compiler.internal.tree.as.MemberAccessExpressionNode;
-import org.apache.royale.compiler.internal.tree.as.VariableNode;
 import org.apache.royale.compiler.problems.ICompilerProblem;
 import org.apache.royale.compiler.problems.VariableUsedBeforeDeclarationProblem;
 import org.apache.royale.compiler.projects.ICompilerProject;
@@ -186,6 +182,7 @@
             ITypeNode tnode = EmitterUtils.findTypeNode(definition.getNode());
             if (tnode != null)
             {
+            	getModel().primaryDefinitionQName = formatQualifiedName(type.getQualifiedName());
                 getWalker().walk(tnode); // IClassNode | IInterfaceNode
             }
             return;
@@ -703,7 +700,10 @@
         boolean isLocal = false;
         if (node.getFunctionClassification() == IFunctionDefinition.FunctionClassification.LOCAL)
             isLocal = true;
-        if (EmitterUtils.hasBody(node) && !isStatic && !isLocal)
+        boolean isPackage = false;
+        if (node.getFunctionClassification() == IFunctionDefinition.FunctionClassification.PACKAGE_MEMBER)
+        isPackage = true;
+        if (EmitterUtils.hasBody(node) && !isStatic && !isLocal && !isPackage)
             emitSelfReference(node);
 
         if (node.isConstructor()
@@ -954,22 +954,15 @@
         }
         else
         {
-            // AJH need Language.bind here and maybe not require
-            // that the node is a MemberAccessExpression
-            if (definition instanceof FunctionDefinition &&
-                    !((FunctionDefinition)definition).isStatic() &&
-                    (!(definition instanceof AccessorDefinition)) &&
-                    node instanceof MemberAccessExpressionNode &&
-                    ((MemberAccessExpressionNode)node).getLeftOperandNode().getNodeID() != ASTNodeID.SuperID)
+            if (definition instanceof IFunctionDefinition &&
+            		node.getNodeID() == ASTNodeID.NamespaceAccessExpressionID)
             {
-                emitClosureStart();
-                getWalker().walk(node);
-                writeToken(ASEmitterTokens.COMMA);
-                getWalker().walk(((MemberAccessExpressionNode)node).getLeftOperandNode());
-                emitClosureEnd(((MemberAccessExpressionNode)node).getLeftOperandNode(), definition);
+            	// can't do normal walk.  Need to generate closure
+            	// so walk just the right operand
+            	getWalker().walk(node.getChild(1));
             }
             else
-                getWalker().walk(node);
+            	getWalker().walk(node);
         }
     }
 
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JSGoogPublisher.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JSGoogPublisher.java
index 45c14a9..97dd8d4 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JSGoogPublisher.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JSGoogPublisher.java
@@ -111,14 +111,14 @@
                 DirectoryFileFilter.DIRECTORY);
         for (File file : files)
         {
-            inputs.add(SourceFile.fromFile(file));
+            inputs.add(SourceFile.fromFile(file.getAbsolutePath()));
         }
 
         copyFile(closureGoogSrcLibDir, closureGoogTgtLibDir);
         copyFile(closureTPSrcLibDir, closureTPTgtLibDir);
 
         final List<SourceFile> deps = new ArrayList<SourceFile>();
-        deps.add(SourceFile.fromFile(depsSrcFile));
+        deps.add(SourceFile.fromFile(depsSrcFile.getAbsolutePath()));
 
         ErrorManager errorManager = new JSGoogErrorManager();
         DepsGenerator depsGenerator = new DepsGenerator(deps, inputs,
@@ -322,6 +322,7 @@
                 {
                     if (!dir.mkdirs())
                     {
+                        jar.close();
                         throw new IOException("Unable to create directory "
                                 + dir.getAbsolutePath());
                     }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JarSourceFile.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JarSourceFile.java
index 8878f62..1f97c80 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JarSourceFile.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/goog/JarSourceFile.java
@@ -19,7 +19,6 @@
 
 package org.apache.royale.compiler.internal.codegen.js.goog;
 
-import com.google.common.io.CharSource;
 import com.google.javascript.jscomp.Region;
 import com.google.javascript.jscomp.SourceFile;
 
@@ -32,12 +31,16 @@
  */
 public class JarSourceFile extends SourceFile {
 
-    private String fileName;
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = -3821969963886712441L;
+	private String fileName;
     private boolean isExtern;
     private String code;
 
     public JarSourceFile(String fileName, String code, boolean isExtern) {
-        super(fileName);
+        super(fileName, isExtern ? SourceKind.EXTERN : SourceKind.STRONG);
         this.fileName = fileName;
         this.isExtern = isExtern;
         this.code = code;
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/AccessorEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/AccessorEmitter.java
index ce3fd25..dcaeacf 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/AccessorEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/AccessorEmitter.java
@@ -105,7 +105,7 @@
                     if (emitExports)
                     	writeNewline("  * @export");
                     if (p.type != null)
-                    	writeNewline("  * @type {"+JSGoogDocEmitter.convertASTypeToJSType(p.type.getBaseName(), p.type.getPackageName()) + "} */");
+                    	writeNewline("  * @type {"+ JSGoogDocEmitter.convertASTypeToJSType(p.type.getBaseName(), p.type.getPackageName()) + "} */");
                     else
                     	writeNewline("  */");
                     write(getEmitter().formatQualifiedName(qname));
@@ -117,7 +117,7 @@
             			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
             			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
             			String s = nsDef.getURI();
-            			write("[\"" + s + "::" + propName + "\"]");
+            			write(JSRoyaleEmitter.formatNamespacedProperty(s, propName, true));
                     }
                     else
                     {
@@ -143,7 +143,7 @@
 	            			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
 	            			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
 	            			String s = nsDef.getURI();
-	            			write("[\"" + s + "::" + JSRoyaleEmitterTokens.GETTER_PREFIX.getToken() + propName + "\"]");
+	            			write(JSRoyaleEmitter.formatNamespacedProperty(s, JSRoyaleEmitterTokens.GETTER_PREFIX.getToken() + propName, true));
 	                    }
 	                    else
 	                    {
@@ -205,7 +205,7 @@
 	            			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
 	            			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
 	            			String s = nsDef.getURI();
-	            			write("[\"" + s + "::" + JSRoyaleEmitterTokens.SETTER_PREFIX.getToken() + propName + "\"]");
+	            			write(JSRoyaleEmitter.formatNamespacedProperty(s, JSRoyaleEmitterTokens.SETTER_PREFIX.getToken() + propName, true));
 	                    }
 	                    else
 	                    {
@@ -321,7 +321,12 @@
                 if (emitExports)
                 	writeNewline("  * @export");
                 if (p.type != null)
-                	writeNewline("  * @type {"+JSGoogDocEmitter.convertASTypeToJSType(p.type.getBaseName(), p.type.getPackageName()) + "} */");
+                {
+                	String typeName = p.type.getBaseName();
+                	if (getModel().isInternalClass(typeName))
+    					typeName = getModel().getInternalClasses().get(typeName);
+					writeNewline("  * @type {" + JSGoogDocEmitter.convertASTypeToJSType(typeName, p.type.getPackageName()) + "} */");
+                }
                 else
                 	writeNewline("  */");
                 FunctionNode fnNode = getterNode != null ? (FunctionNode) getterNode : (FunctionNode) setterNode;
@@ -331,7 +336,7 @@
         			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
         			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
         			String s = nsDef.getURI();
-        			write("\"" + s + "::" + propName + "\"");
+        			write(JSRoyaleEmitter.formatNamespacedProperty(s, propName, false));
                 }
                 else
                 	write(propName);
@@ -353,7 +358,7 @@
             			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
             			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
             			String s = nsDef.getURI();
-            			write("[\"" + s + "::" + JSRoyaleEmitterTokens.GETTER_PREFIX.getToken() + propName + "\"]");
+            			write(JSRoyaleEmitter.formatNamespacedProperty(s, JSRoyaleEmitterTokens.GETTER_PREFIX.getToken() + propName, true));
                     }
                     else
                     {
@@ -386,7 +391,7 @@
                 			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
                 			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
                 			String s = nsDef.getURI();
-                			write("[\"" + s + "::" + JSRoyaleEmitterTokens.GETTER_PREFIX.getToken() + propName + "\"]");
+                			write(JSRoyaleEmitter.formatNamespacedProperty(s, JSRoyaleEmitterTokens.GETTER_PREFIX.getToken() + propName, true));
                         }
                         else
                         {
@@ -414,7 +419,7 @@
             			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
             			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
             			String s = nsDef.getURI();
-            			write("[\"" + s + "::" + JSRoyaleEmitterTokens.SETTER_PREFIX.getToken() + propName + "\"]");
+            			write(JSRoyaleEmitter.formatNamespacedProperty(s, JSRoyaleEmitterTokens.SETTER_PREFIX.getToken() + propName, true));
                     }
                     else
                     {
@@ -448,7 +453,7 @@
                 			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
                 			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
                 			String s = nsDef.getURI();
-                			write("[\"" + s + "::" + JSRoyaleEmitterTokens.SETTER_PREFIX.getToken() + propName + "\"]");
+                			write(JSRoyaleEmitter.formatNamespacedProperty(s, JSRoyaleEmitterTokens.SETTER_PREFIX.getToken() + propName, true));
                         }
                         else
                         {
@@ -483,7 +488,7 @@
                     if (emitExports)
                     	writeNewline("  * @export");
                     if (p.type != null)
-                    	writeNewline("  * @type {"+JSGoogDocEmitter.convertASTypeToJSType(p.type.getBaseName(), p.type.getPackageName()) + "} */");
+                    	writeNewline("  * @type {" + JSGoogDocEmitter.convertASTypeToJSType(p.type.getBaseName(), p.type.getPackageName()) + "} */");
                     else
                     	writeNewline("  */");
                     write(getEmitter().formatQualifiedName(qname));
@@ -493,7 +498,7 @@
             			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
             			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
             			String s = nsDef.getURI();
-            			write("[\"" + s + "::" + propName + "\"]");
+            			write(JSRoyaleEmitter.formatNamespacedProperty(s, propName, true));
                     }
                     else
                     {
@@ -516,7 +521,7 @@
 	            			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
 	            			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
 	            			String s = nsDef.getURI();
-	            			write("[\"" + s + "::" + JSRoyaleEmitterTokens.GETTER_PREFIX.getToken() + propName + "\"]");
+	            			write(JSRoyaleEmitter.formatNamespacedProperty(s, JSRoyaleEmitterTokens.GETTER_PREFIX.getToken() + propName, true));
 	                    }
 	                    else
 	                    {
@@ -546,7 +551,7 @@
 	            			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
 	            			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
 	            			String s = nsDef.getURI();
-	            			write("[\"" + s + "::" + JSRoyaleEmitterTokens.SETTER_PREFIX.getToken() + propName + "\"]");
+	            			write(JSRoyaleEmitter.formatNamespacedProperty(s, JSRoyaleEmitterTokens.SETTER_PREFIX.getToken() + propName, true));
 	                    }
 	                    else
 	                    {
@@ -602,7 +607,7 @@
                 if (emitExports)
                 	writeNewline("  * @export");
                 if (p.type != null)
-                	writeNewline("  * @type {"+JSGoogDocEmitter.convertASTypeToJSType(p.type.getBaseName(), p.type.getPackageName()) + "} */");
+                	writeNewline("  * @type {" + JSGoogDocEmitter.convertASTypeToJSType(p.type.getBaseName(), p.type.getPackageName()) + "} */");
                 else
                 	writeNewline("  */");
                 write(propName);
@@ -622,7 +627,7 @@
             			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
             			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
             			String s = nsDef.getURI();
-            			write("[\"" + s + "::" + JSRoyaleEmitterTokens.GETTER_PREFIX.getToken() + propName + "\"]");
+            			write(JSRoyaleEmitter.formatNamespacedProperty(s, JSRoyaleEmitterTokens.GETTER_PREFIX.getToken() + propName, true));
                     }
                     else
                     {
@@ -646,7 +651,7 @@
             			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
             			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
             			String s = nsDef.getURI();
-            			write("[\"" + s + "::" + JSRoyaleEmitterTokens.SETTER_PREFIX.getToken() + propName + "\"]");
+            			write(JSRoyaleEmitter.formatNamespacedProperty(s, JSRoyaleEmitterTokens.SETTER_PREFIX.getToken() + propName, true));
                     }
                     else
                     {
@@ -663,7 +668,7 @@
         }
     }
 
-    public void emitGet(IGetterNode node)
+	public void emitGet(IGetterNode node)
     {
         // TODO (mschmalle) will remove this cast as more things get abstracted
         JSRoyaleEmitter fjs = (JSRoyaleEmitter) getEmitter();
@@ -675,8 +680,8 @@
         HashMap<String, PropertyNodes> map = isStatic ? getModel()
                 .getStaticPropertyMap() : getModel().getPropertyMap();
         String name = node.getName();
-    	if (!isStatic && def != null && def.isPrivate() && getProject().getAllowPrivateNameConflicts())
-    		name = fjs.formatPrivateName(def.getParent().getQualifiedName(), name);
+    		if (!isStatic && def != null && def.isPrivate() && getProject().getAllowPrivateNameConflicts())
+    			name = fjs.formatPrivateName(def.getParent().getQualifiedName(), name);
         PropertyNodes p = map.get(name);
         if (p == null)
         {
@@ -704,8 +709,8 @@
         HashMap<String, PropertyNodes> map = isStatic ? getModel()
                 .getStaticPropertyMap() : getModel().getPropertyMap();
         String name = node.getName();
-    	if (!isStatic && def != null && def.isPrivate() && getProject().getAllowPrivateNameConflicts())
-    		name = fjs.formatPrivateName(def.getParent().getQualifiedName(), name);
+    		if (!isStatic && def != null && def.isPrivate() && getProject().getAllowPrivateNameConflicts())
+    			name = fjs.formatPrivateName(def.getParent().getQualifiedName(), name);
         PropertyNodes p = map.get(name);
         if (p == null)
         {
@@ -758,6 +763,7 @@
             fjs.emitParameters(node.getParametersContainerNode());
             //writeNewline();
             fjs.emitMethodScope(node.getScopedNode());
+			writeNewline();
         }
     }
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/AsIsEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/AsIsEmitter.java
index e8ffe98..9ddea56 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/AsIsEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/AsIsEmitter.java
@@ -22,6 +22,7 @@
 import org.apache.royale.compiler.asdoc.royale.ASDocComment;
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
 import org.apache.royale.compiler.constants.IASLanguageConstants;
+import org.apache.royale.compiler.definitions.IAppliedVectorDefinition;
 import org.apache.royale.compiler.definitions.IClassDefinition;
 import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
@@ -29,12 +30,14 @@
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
+import org.apache.royale.compiler.parsing.IASToken;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IASNode;
 import org.apache.royale.compiler.tree.as.IBinaryOperatorNode;
 import org.apache.royale.compiler.tree.as.IExpressionNode;
 import org.apache.royale.compiler.tree.as.IFunctionNode;
+import org.apache.royale.compiler.utils.NativeUtils;
 
 public class AsIsEmitter extends JSSubEmitter
 {
@@ -53,7 +56,7 @@
                 .resolve(getProject()) : null;
         if (id != ASTNodeID.Op_IsID && dnode != null)
         {
-            boolean emit = coercion ? 
+            boolean emit = coercion ?
             		!((RoyaleJSProject)getProject()).config.getJSOutputOptimizations().contains(JSRoyaleEmitterTokens.SKIP_FUNCTION_COERCIONS.getToken()) :
                 	!((RoyaleJSProject)getProject()).config.getJSOutputOptimizations().contains(JSRoyaleEmitterTokens.SKIP_AS_COERCIONS.getToken());
             			
@@ -147,7 +150,7 @@
         getEmitter().getModel().needLanguage = true;
         if (node instanceof IBinaryOperatorNode)
         {
-            IBinaryOperatorNode binaryOperatorNode = (IBinaryOperatorNode) node; 
+            IBinaryOperatorNode binaryOperatorNode = (IBinaryOperatorNode) node;
             startMapping(node, binaryOperatorNode.getLeftOperandNode());
         }
         else
@@ -181,7 +184,29 @@
         if (dnode instanceof IClassDefinition)
         {
             startMapping(right);
-            write(getEmitter().formatQualifiedName(((JSRoyaleEmitter)getEmitter()).convertASTypeToJS(dnode.getQualifiedName())));
+            if (NativeUtils.isSyntheticJSType(dnode.getQualifiedName())) {
+                JSRoyaleEmitterTokens langMethod;
+                String synthName;
+                if (NativeUtils.isVector(dnode.getQualifiedName()) && dnode instanceof IAppliedVectorDefinition) {
+                    langMethod = JSRoyaleEmitterTokens.SYNTH_VECTOR;
+                    synthName = getEmitter().formatQualifiedName(((IAppliedVectorDefinition) dnode).resolveElementType(project).getQualifiedName());
+                } else {
+                    //non-vector, e.g. int/uint
+                    langMethod = JSRoyaleEmitterTokens.SYNTH_TYPE;
+                    synthName = getEmitter().formatQualifiedName(dnode.getQualifiedName());
+                }
+                write(langMethod);
+                write(ASEmitterTokens.PAREN_OPEN);
+                write(ASEmitterTokens.SINGLE_QUOTE);
+                write(synthName);
+                write(ASEmitterTokens.SINGLE_QUOTE);
+                write(ASEmitterTokens.PAREN_CLOSE);
+                if (project instanceof RoyaleJSProject)
+                    ((RoyaleJSProject)project).needLanguage = true;
+                getEmitter().getModel().needLanguage = true;
+            } else {
+                write(getEmitter().formatQualifiedName(((JSRoyaleEmitter)getEmitter()).convertASTypeToJS(dnode.getQualifiedName())));
+            }
             endMapping(right);
         }
         else
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
index 756c3d8..e55ed32 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
@@ -21,24 +21,23 @@
 
 import org.apache.royale.compiler.codegen.ISubEmitter;
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
-import org.apache.royale.compiler.constants.IASLanguageConstants;
 import org.apache.royale.compiler.definitions.IDefinition;
+import org.apache.royale.compiler.definitions.IFunctionDefinition;
+import org.apache.royale.compiler.definitions.IFunctionDefinition.FunctionClassification;
 import org.apache.royale.compiler.definitions.ITypeDefinition;
-import org.apache.royale.compiler.definitions.metadata.IMetaTag;
-import org.apache.royale.compiler.definitions.metadata.IMetaTagAttribute;
+import org.apache.royale.compiler.definitions.IVariableDefinition;
+import org.apache.royale.compiler.definitions.IVariableDefinition.VariableClassification;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSSubEmitter;
-import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleDocEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
 import org.apache.royale.compiler.internal.definitions.AccessorDefinition;
-import org.apache.royale.compiler.internal.tree.as.DynamicAccessNode;
-import org.apache.royale.compiler.internal.tree.as.FunctionCallNode;
-import org.apache.royale.compiler.internal.tree.as.IdentifierNode;
-import org.apache.royale.compiler.internal.tree.as.MemberAccessExpressionNode;
-import org.apache.royale.compiler.internal.tree.as.UnaryOperatorAtNode;
+import org.apache.royale.compiler.internal.definitions.AppliedVectorDefinition;
+import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
+import org.apache.royale.compiler.internal.semantics.SemanticUtils;
+import org.apache.royale.compiler.internal.tree.as.*;
 import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IASNode;
 import org.apache.royale.compiler.tree.as.IBinaryOperatorNode;
@@ -91,11 +90,44 @@
 
             IDefinition dnode = (node.getRightOperandNode())
                     .resolve(getProject());
-            if (dnode != null)
-                write(getEmitter()
-                        .formatQualifiedName(dnode.getQualifiedName()));
-            else
-                getWalker().walk(node.getRightOperandNode());
+			if (dnode != null)
+			{
+				String dnodeQname = dnode.getQualifiedName();
+                boolean isPackageOrFileMember = false;
+                if (dnode instanceof IVariableDefinition)
+                {
+                    IVariableDefinition variable = (IVariableDefinition) dnode;
+                    VariableClassification classification = variable.getVariableClassification();
+                    if (classification == VariableClassification.PACKAGE_MEMBER ||
+                            classification == VariableClassification.FILE_MEMBER)
+                    {
+                        isPackageOrFileMember = true;
+                    }
+                }
+                else if (dnode instanceof IFunctionDefinition)
+                {
+                    IFunctionDefinition func = (IFunctionDefinition) dnode;
+                    FunctionClassification classification = func.getFunctionClassification();
+                    if (classification == FunctionClassification.PACKAGE_MEMBER ||
+                            classification == FunctionClassification.FILE_MEMBER)
+                    {
+                        isPackageOrFileMember = true;
+                    }
+                }
+				else if(dnode instanceof ITypeDefinition)
+				{
+					isPackageOrFileMember = true;
+				}
+				if(isPackageOrFileMember)
+				{
+					dnodeQname = getEmitter().formatQualifiedName(dnodeQname);
+				}
+                write(dnodeQname);
+			}
+			else
+			{
+				getWalker().walk(node.getRightOperandNode());
+			}
         }
         else
         {
@@ -105,7 +137,7 @@
             {
                 IASNode lnode = leftSide.getChild(0);
                 IASNode rnode = leftSide.getChild(1);
-                IDefinition rnodeDef = (rnode instanceof IIdentifierNode) ? 
+                IDefinition rnodeDef = (rnode instanceof IIdentifierNode) ?
                 		((IIdentifierNode) rnode).resolve(getWalker().getProject()) :
                 		null;
                 boolean isDynamicAccess = rnode instanceof DynamicAccessNode;
@@ -122,7 +154,7 @@
                         else
                         	write(getEmitter().formatQualifiedName(
                         		getModel().getCurrentClass().getQualifiedName()));
-                        			
+                        		
                         write(ASEmitterTokens.MEMBER_ACCESS);
                         write(JSGoogEmitterTokens.SUPERCLASS);
                         write(ASEmitterTokens.MEMBER_ACCESS);
@@ -318,7 +350,7 @@
             else if (leftSide.getNodeID() == ASTNodeID.IdentifierID)
             {
     			if ((leftDef != null)
-    				&& IdentifierNode.isXMLish(leftDef, getWalker().getProject()))
+    				&& SemanticUtils.isXMLish(leftDef, getWalker().getProject()))
     			{
                 	if (node.getNodeID() == ASTNodeID.Op_AddAssignID)
                 	{
@@ -396,161 +428,13 @@
 
     			}
             }
-
-            boolean leftIsNumber = (leftDef != null && (leftDef.getQualifiedName().equals(IASLanguageConstants.Number) ||
-					  leftDef.getQualifiedName().equals(IASLanguageConstants._int) ||
-					  leftDef.getQualifiedName().equals(IASLanguageConstants.uint)));
-        	IExpressionNode rNode = node.getRightOperandNode();
-        	IDefinition rightDef = rNode.resolveType(getWalker().getProject());
-        	boolean rightIsNumber = (rightDef != null && (rightDef.getQualifiedName().equals(IASLanguageConstants.Number) ||
-					  rightDef.getQualifiedName().equals(IASLanguageConstants._int) ||
-					  rightDef.getQualifiedName().equals(IASLanguageConstants.uint)));
-            if (leftIsNumber && !rightIsNumber && (rightDef == null || rightDef.getQualifiedName().equals(IASLanguageConstants.ANY_TYPE)))
-            {
-        		if (rNode.getNodeID() == ASTNodeID.FunctionCallID)
-        		{
-	            	IExpressionNode fnNameNode = ((FunctionCallNode)rNode).getNameNode();
-	            	if (fnNameNode.getNodeID() == ASTNodeID.MemberAccessExpressionID)
-	            	{
-	            		MemberAccessExpressionNode mae = (MemberAccessExpressionNode)fnNameNode;
-	            		IExpressionNode rightNode = mae.getRightOperandNode();
-	            		rightIsNumber = rightNode.getNodeID() == ASTNodeID.IdentifierID && 
-	            				((IdentifierNode)rightNode).getName().equals("length") &&
-	            				fjs.isXMLList(mae);
-	            	}
-        		}
-        		else if (rNode.getNodeID() == ASTNodeID.ArrayIndexExpressionID)
-        		{
-        			DynamicAccessNode dyn = (DynamicAccessNode)rNode;
-        			IDefinition lDef = dyn.getLeftOperandNode().resolveType(getProject());
-        			IDefinition rDef = dyn.getRightOperandNode().resolveType(getProject());
-        			// numeric indexing?
-        			if (rDef.getQualifiedName().equals(IASLanguageConstants.Number))
-        			{
-        				IMetaTag[] metas = lDef.getAllMetaTags();
-        				for (IMetaTag meta : metas)
-        				{
-        					if (meta.getTagName().equals("ArrayElementType"))
-        					{
-        						IMetaTagAttribute[] attrs = meta.getAllAttributes();
-        						for (IMetaTagAttribute attr : attrs)
-        						{
-        							String t = attr.getValue();
-            						if (t.equals(IASLanguageConstants.Number))
-            							rightIsNumber = true;
-        						}
-        					}
-        				}
-        			}
-        		}
-            }
-            String coercion = (leftIsNumber && !rightIsNumber && isAssignment) ? "Number(" : "";
-            if (isAssignment && leftDef != null && leftDef.getQualifiedName().equals(IASLanguageConstants.String))
-            {
-            	if (rNode.getNodeID() != ASTNodeID.LiteralStringID &&
-            			rNode.getNodeID() != ASTNodeID.LiteralNullID)
-            	{
-		        	if (rightDef == null ||
-		        			(!(rightDef.getQualifiedName().equals(IASLanguageConstants.String) ||
-		        			  (rightDef.getQualifiedName().equals(IASLanguageConstants.ANY_TYPE)
-		                    		&& rNode.getNodeID() == ASTNodeID.FunctionCallID &&
-		                    		isToString(rNode)) ||
-		        			  // if not an assignment we don't need to coerce numbers
-		        			  (!isAssignment && rightIsNumber) ||
-		        			   rightDef.getQualifiedName().equals(IASLanguageConstants.Null))))
-		        	{
-		        		JSRoyaleDocEmitter docEmitter = (JSRoyaleDocEmitter)(getEmitter().getDocEmitter());
-		        		if (docEmitter.emitStringConversions)
-		        		{
-		        			coercion = "org.apache.royale.utils.Language.string(";
-		        		}
-		        	}
-            	}
-            }
-            super_emitBinaryOperator(node, coercion);
-            if (coercion.length() > 0)
-            	write(")");
-            	
-            /*
-            IExpressionNode leftSide = node.getLeftOperandNode();
-
-            IExpressionNode property = null;
-            int leftSideChildCount = leftSide.getChildCount();
-            if (leftSideChildCount > 0)
-            {
-                IASNode childNode = leftSide.getChild(leftSideChildCount - 1);
-                if (childNode instanceof IExpressionNode)
-                    property = (IExpressionNode) childNode;
-                else
-                    property = leftSide;
-            }
-            else
-                property = leftSide;
-
-            IDefinition def = null;
-            if (property instanceof IIdentifierNode)
-                def = ((IIdentifierNode) property).resolve(getWalker()
-                        .getProject());
-
-            boolean isSuper = false;
-            if (leftSide.getNodeID() == ASTNodeID.MemberAccessExpressionID)
-            {
-                IASNode cnode = leftSide.getChild(0);
-                ASTNodeID cId = cnode.getNodeID();
-
-                isSuper = cId == ASTNodeID.SuperID;
-            }
-
-            String op = node.getOperator().getOperatorText();
-            boolean isAssignment = op.contains("=") && !op.contains("==") && 
-                                                    !(op.startsWith("<") || 
-                                                            op.startsWith(">") || 
-                                                            op.startsWith("!"));
-
-            if (def instanceof AccessorDefinition && isAssignment)
-            {
-                // this will make the set_foo call
-                getWalker().walk(leftSide);
-            }
-            else if (isSuper) 
-            {
-                emitSuperCall(node, "");
-            }
-            else
-            {
-                if (ASNodeUtils.hasParenOpen(node))
-                    write(ASEmitterTokens.PAREN_OPEN);
-
-                getWalker().walk(leftSide);
-
-                if (node.getNodeID() != ASTNodeID.Op_CommaID)
-                    write(ASEmitterTokens.SPACE);
-
-                writeToken(node.getOperator().getOperatorText());
-
-                getWalker().walk(node.getRightOperandNode());
-
-                if (ASNodeUtils.hasParenClose(node))
-                    write(ASEmitterTokens.PAREN_CLOSE);
-            }
-            */
+		
+			super_emitBinaryOperator(node, isAssignment);
         }
     }
     
-    private boolean isToString(IASNode rNode)
-    {
-    	IExpressionNode fnNameNode = ((FunctionCallNode)rNode).getNameNode();
-    	if (fnNameNode.getNodeID() == ASTNodeID.MemberAccessExpressionID)
-    	{
-    		MemberAccessExpressionNode mae = (MemberAccessExpressionNode)fnNameNode;
-    		IExpressionNode rightNode = mae.getRightOperandNode();
-    		return rightNode.getNodeID() == ASTNodeID.IdentifierID && 
-    				((IdentifierNode)rightNode).getName().equals("toString");
-    	}
-    	return false;
-    }
 
-    private void super_emitBinaryOperator(IBinaryOperatorNode node, String coercion)
+    private void super_emitBinaryOperator(IBinaryOperatorNode node, boolean isAssignment)
     {
         if (ASNodeUtils.hasParenOpen(node))
             write(ASEmitterTokens.PAREN_OPEN);
@@ -585,8 +469,28 @@
         }
         else
         {
-            getWalker().walk(node.getLeftOperandNode());
-
+			if (isAssignment
+					&& (getProject() instanceof RoyaleJSProject && ((RoyaleJSProject) getProject()).config != null && ((RoyaleJSProject) getProject()).config.getJsVectorEmulationClass() == null)
+					&& node.getLeftOperandNode() instanceof MemberAccessExpressionNode
+					&& ((MemberAccessExpressionNode) node.getLeftOperandNode()).getRightOperandNode() instanceof IdentifierNode
+					&& ((IdentifierNode) ((MemberAccessExpressionNode) node.getLeftOperandNode()).getRightOperandNode()).getName().equals("length")
+					&& ((MemberAccessExpressionNode) node.getLeftOperandNode()).getLeftOperandNode().resolveType(getProject()) instanceof AppliedVectorDefinition)
+			{
+				//for default Vector implementation, when setting length, we need to set it on the associated 'synthType' instance which tags the native
+				//Array representation of the Vector. This allows running 'setter' code because it is not possible to override the native length setter on Array
+				//unless using a different approach, like es6 Proxy.
+				//this code inserts the extra access name for setting length, e.g. myVectInstance['_synthType'].length = assignedValue
+				//the dynamic access field name is a constant on Language, so it can be different/shorter in release build
+				getWalker().walk(((MemberAccessExpressionNode) node.getLeftOperandNode()).getLeftOperandNode());
+				write(ASEmitterTokens.SQUARE_OPEN);
+				write(JSRoyaleEmitterTokens.LANGUAGE_QNAME.getToken());
+				write(ASEmitterTokens.MEMBER_ACCESS);
+				write(JSRoyaleEmitterTokens.ROYALE_SYNTH_TAG_FIELD_NAME);
+				write(ASEmitterTokens.SQUARE_CLOSE);
+				write(ASEmitterTokens.MEMBER_ACCESS);
+				getWalker().walk(((MemberAccessExpressionNode) node.getLeftOperandNode()).getRightOperandNode());
+			}
+            else getWalker().walk(node.getLeftOperandNode());
             startMapping(node, node.getLeftOperandNode());
             
             if (id != ASTNodeID.Op_CommaID)
@@ -617,25 +521,26 @@
             write(ASEmitterTokens.SPACE);
             endMapping(node);
 
-            write(coercion);
-            /*
-            IDefinition definition = node.getRightOperandNode().resolve(getProject());
-        	if (definition instanceof FunctionDefinition &&
-        			(!(definition instanceof AccessorDefinition)))
-        	{
-        	}
-        	else */
-        		getWalker().walk(node.getRightOperandNode());
-                if (node.getNodeID() == ASTNodeID.Op_InID &&
-                        ((JSRoyaleEmitter)getEmitter()).isXML(node.getRightOperandNode()))
-                {
-                	write(".elementNames()");
-                }   
-                else if (node.getNodeID() == ASTNodeID.Op_InID &&
-                        ((JSRoyaleEmitter)getEmitter()).isProxy(node.getRightOperandNode()))
-                {
-                	write(".propertyNames()");
-                }
+			if (isAssignment)
+			{
+				getEmitter().emitAssignmentCoercion(node.getRightOperandNode(), node.getLeftOperandNode().resolveType(getProject()));
+			}
+			else
+			{
+				
+				getWalker().walk(node.getRightOperandNode());
+				
+				if (node.getNodeID() == ASTNodeID.Op_InID &&
+						((JSRoyaleEmitter)getEmitter()).isXML(node.getRightOperandNode()))
+				{
+					write(".elementNames()");
+				}
+				else if (node.getNodeID() == ASTNodeID.Op_InID &&
+						((JSRoyaleEmitter)getEmitter()).isProxy(node.getRightOperandNode()))
+				{
+					write(".propertyNames()");
+				}
+			}
         }
 
         if (ASNodeUtils.hasParenOpen(node))
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BindableEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BindableEmitter.java
index cbefd7e..b1c1527 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BindableEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BindableEmitter.java
@@ -447,7 +447,7 @@
     {
         // TODO (mschmalle) will remove this cast as more things get abstracted
         JSRoyaleEmitter fjs = (JSRoyaleEmitter) getEmitter();
-    	String qname = info.namespace.equals("private") ? fjs.formatPrivateName(cdef.getQualifiedName(), name) : name;
+    		String qname = (info.namespace.equals("private") && getProject().getAllowPrivateNameConflicts()) ? fjs.formatPrivateName(cdef.getQualifiedName(), name) : name;
         if (info.namespace != "public") {
             writeNewline("/** @export");
             writeNewline("  * @private");
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ClassEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ClassEmitter.java
index 6c3ddda..4c1877d 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ClassEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ClassEmitter.java
@@ -19,6 +19,8 @@
 
 package org.apache.royale.compiler.internal.codegen.js.jx;
 
+import java.util.List;
+
 import org.apache.royale.compiler.asdoc.royale.ASDocComment;
 import org.apache.royale.compiler.codegen.ISubEmitter;
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
@@ -55,9 +57,11 @@
     @Override
     public void emit(IClassNode node)
     {
-    	boolean keepASDoc = false;
+        boolean keepASDoc = false;
+        boolean verbose = false;
         RoyaleJSProject project = (RoyaleJSProject)getEmitter().getWalker().getProject();
         keepASDoc = project.config != null && project.config.getKeepASDoc();
+        verbose = project.config != null && project.config.isVerbose();
     	
         getModel().pushClass(node.getDefinition());
 
@@ -66,7 +70,20 @@
         
         ASDocComment asDoc = (ASDocComment) node.getASDocComment();
         if (asDoc != null && keepASDoc)
-            DocEmitterUtils.loadImportIgnores(fjs, asDoc.commentNoEnd());
+        {
+            List<String> ignoreList = DocEmitterUtils.loadImportIgnores(fjs, asDoc.commentNoEnd());
+            if(verbose)
+            {
+                for(String ignorable : ignoreList)
+                {
+                    System.out.println("Found ignorable: " + ignorable);
+                }
+            }
+        }
+        
+        boolean suppressExport = (asDoc != null && DocEmitterUtils.hasSuppressExport(fjs, asDoc.commentNoEnd()));
+
+        getModel().suppressExports = suppressExport;
 
         IClassDefinition definition = node.getDefinition();
 
@@ -131,7 +148,7 @@
             }
         }
 
-  	    if (!getEmitter().getModel().isExterns)
+  	    if (!getEmitter().getModel().isExterns && !suppressExport)
   	    {
   	        JSRoyaleDocEmitter doc = (JSRoyaleDocEmitter) getEmitter()
   	        .getDocEmitter();
@@ -246,8 +263,8 @@
                     write(ASEmitterTokens.MEMBER_ACCESS);
                     String dname = dnode.getName();
                     IDefinition dDef = dnode.getDefinition();
-                	if (dDef != null && dDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
-                		dname = getEmitter().formatPrivateName(dDef.getParent().getQualifiedName(), dname);
+                		if (dDef != null && dDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
+                			dname = getEmitter().formatPrivateName(dDef.getParent().getQualifiedName(), dname);
                     write(dname);
                     if (dnode.getNodeID() == ASTNodeID.BindableVariableID)
                     {
@@ -255,7 +272,7 @@
                     }
                     write(ASEmitterTokens.SPACE);
                     writeToken(ASEmitterTokens.EQUAL);
-                    getEmitter().getWalker().walk(vnode);
+                    getEmitter().emitAssignmentCoercion(vnode, varnode.getVariableTypeNode().resolve(getProject()));
                     write(ASEmitterTokens.SEMICOLON);
                     wroteOne = true;
                 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/DynamicAccessEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/DynamicAccessEmitter.java
index 33231d1..5b78317 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/DynamicAccessEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/DynamicAccessEmitter.java
@@ -19,17 +19,30 @@
 
 package org.apache.royale.compiler.internal.codegen.js.jx;
 
+import org.apache.royale.compiler.codegen.IDocEmitter;
 import org.apache.royale.compiler.codegen.ISubEmitter;
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
+import org.apache.royale.compiler.constants.IASLanguageConstants;
 import org.apache.royale.compiler.definitions.ITypeDefinition;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.royale.compiler.internal.codegen.js.JSEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleDocEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter;
+import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens;
+import org.apache.royale.compiler.internal.definitions.AppliedVectorDefinition;
+import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
+import org.apache.royale.compiler.internal.tree.as.BinaryOperatorAssignmentNode;
+import org.apache.royale.compiler.internal.tree.as.FunctionCallNode;
+import org.apache.royale.compiler.internal.tree.as.IdentifierNode;
 import org.apache.royale.compiler.internal.tree.as.MemberAccessExpressionNode;
-import org.apache.royale.compiler.internal.tree.as.NumericLiteralNode;
+import org.apache.royale.compiler.parsing.IASToken;
 import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IDynamicAccessNode;
 import org.apache.royale.compiler.tree.as.IExpressionNode;
+import org.apache.royale.compiler.tree.as.ILiteralNode;
+import org.apache.royale.compiler.tree.as.IOperatorNode.OperatorType;
+import org.apache.royale.compiler.utils.NativeUtils;
 
 public class DynamicAccessEmitter extends JSSubEmitter implements
         ISubEmitter<IDynamicAccessNode>
@@ -48,19 +61,24 @@
         	return;
 
         IExpressionNode rightOperandNode = node.getRightOperandNode();
+		ITypeDefinition type = rightOperandNode.resolveType(getProject());
         IJSEmitter ijs = getEmitter();
     	JSRoyaleEmitter fjs = (ijs instanceof JSRoyaleEmitter) ? 
     							(JSRoyaleEmitter)ijs : null;
     	if (fjs != null)
     	{
+        	boolean isProxy = false;
 	    	boolean isXML = false;
 	    	if (leftOperandNode instanceof MemberAccessExpressionNode)
 	    		isXML = fjs.isLeftNodeXMLish((MemberAccessExpressionNode)leftOperandNode);
 	    	else if (leftOperandNode instanceof IExpressionNode)
 	    		isXML = fjs.isXML((IExpressionNode)leftOperandNode);
+        	if (leftOperandNode instanceof MemberAccessExpressionNode)
+        		isProxy = fjs.isProxy((MemberAccessExpressionNode)leftOperandNode);
+        	else if (leftOperandNode instanceof IExpressionNode)
+        		isProxy = fjs.isProxy((IExpressionNode)leftOperandNode);
 	    	if (isXML)
 	    	{
-	    		ITypeDefinition type = rightOperandNode.resolveType(getProject());
 				if (type.isInstanceOf("String", getProject()))
 				{
 					String field = fjs.stringifyNode(rightOperandNode);
@@ -74,14 +92,70 @@
 					return;
 				}    		
 	    	}
+        	else if (isProxy)
+        	{
+        		boolean isLiteral = rightOperandNode instanceof ILiteralNode;
+        		write(".getProperty(");
+        		if (isLiteral) write("'");
+        		String s = fjs.stringifyNode(rightOperandNode);
+        		write(s);
+        		if (isLiteral) write("'");
+        		write(")");
+        		return;
+        	}
     	}
     	
         startMapping(node, leftOperandNode);
         write(ASEmitterTokens.SQUARE_OPEN);
         endMapping(node);
+        boolean wrapVectorIndex = false;
+        if (getProject() instanceof RoyaleJSProject) {
+			if (node.getNodeID().equals(ASTNodeID.ArrayIndexExpressionID)){
+				if (node.getParent() instanceof BinaryOperatorAssignmentNode) {
+					if (node.getLeftOperandNode().resolveType(getProject()) instanceof AppliedVectorDefinition) {
+						boolean suppressVectorIndexCheck = !(((RoyaleJSProject)getProject()).config.getJsVectorIndexChecks());
 
+						IDocEmitter docEmitter = getEmitter().getDocEmitter();
+						if (docEmitter instanceof JSRoyaleDocEmitter)
+						{
+							JSRoyaleDocEmitter royaleDocEmitter = (JSRoyaleDocEmitter) docEmitter;
+							//check for local toggle
+							suppressVectorIndexCheck = royaleDocEmitter.getLocalSettingAsBoolean(
+									JSRoyaleEmitterTokens.SUPPRESS_VECTOR_INDEX_CHECK, suppressVectorIndexCheck);
+							
+							if (!suppressVectorIndexCheck) {
+								//check for individual specified suppression, based on variable name
+								if (leftOperandNode instanceof IdentifierNode) {
+									if (royaleDocEmitter.getLocalSettingIncludesString(
+											JSRoyaleEmitterTokens.SUPPRESS_VECTOR_INDEX_CHECK,
+											((IdentifierNode) leftOperandNode).getName()
+									)){
+										suppressVectorIndexCheck = true;
+									}
+								}
+							}
+						}
+						if (!suppressVectorIndexCheck) {
+							getModel().needLanguage = true;
+							((RoyaleJSProject) getProject()).needLanguage = true;
+							getWalker().walk(leftOperandNode);
+							write(ASEmitterTokens.SQUARE_OPEN);
+							write(JSRoyaleEmitterTokens.VECTOR_INDEX_CHECK_METHOD_NAME);
+							write(ASEmitterTokens.SQUARE_CLOSE);
+							write(ASEmitterTokens.PAREN_OPEN);
+							wrapVectorIndex = true;
+						}
+					}
+				}
+			}
+		}
+        
         getWalker().walk(rightOperandNode);
-
+        if (wrapVectorIndex) {
+        	write(ASEmitterTokens.PAREN_CLOSE);
+		}
+        if (type != null && type.getQualifiedName().contentEquals(IASLanguageConstants.QName))
+        	write(".objectAccessFormat()");
         startMapping(node, rightOperandNode);
         write(ASEmitterTokens.SQUARE_CLOSE);
         endMapping(node);
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FieldEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FieldEmitter.java
index c9dddc4..784c9c5 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FieldEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FieldEmitter.java
@@ -25,7 +25,9 @@
 import org.apache.royale.compiler.common.ASModifier;
 import org.apache.royale.compiler.common.ModifiersSet;
 import org.apache.royale.compiler.constants.IASKeywordConstants;
+import org.apache.royale.compiler.definitions.IClassDefinition;
 import org.apache.royale.compiler.definitions.IDefinition;
+import org.apache.royale.compiler.definitions.IFunctionDefinition;
 import org.apache.royale.compiler.definitions.IVariableDefinition;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSEmitterTokens;
@@ -45,6 +47,10 @@
 import org.apache.royale.compiler.tree.metadata.IMetaTagNode;
 import org.apache.royale.compiler.tree.metadata.IMetaTagsNode;
 
+/**
+ * Static or member variables of a class. For local variables in a function, see
+ * VarDeclarationEmitter. For accessors, see AccessorEmitter.
+ */
 public class FieldEmitter extends JSSubEmitter implements
         ISubEmitter<IVariableNode>
 {
@@ -103,8 +109,8 @@
                     + ASEmitterTokens.MEMBER_ACCESS.getToken() + root);
             String qname = node.getName();
             IDefinition nodeDef = node.getDefinition();
-        	if (nodeDef != null && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
-        		qname = getEmitter().formatPrivateName(nodeDef.getParent().getQualifiedName(), qname);
+            if (nodeDef != null && !nodeDef.isStatic() && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
+        			qname = getEmitter().formatPrivateName(nodeDef.getParent().getQualifiedName(), qname);
             write(qname);
             endMapping(node.getNameExpressionNode());
         }
@@ -122,12 +128,12 @@
             String vnodeString = getEmitter().stringifyNode(vnode);
             if (ndef.isStatic() && vnode instanceof FunctionCallNode)
             {
-            	FunctionCallNode fcn = (FunctionCallNode)vnode;
+                FunctionCallNode fcn = (FunctionCallNode)vnode;
             	if (fcn.getNameNode() instanceof IdentifierNode)
             	{
+            		IDefinition d = fcn.getNameNode().resolve(getProject());
             		// assume this is a call to static method in the class
             		// otherwise it would be a memberaccessexpression?
-            		IDefinition d = (IDefinition)fcn.getNameNode().resolve(getProject());
             		if (d instanceof FunctionDefinition)
             		{
             			FunctionDefinition fd = (FunctionDefinition)d;
@@ -137,11 +143,26 @@
     	            		// re-emit it to collect static initializer class references in usedNames
     	            		getEmitter().stringifyNode(m);
                 		}
-            		}
+                    }
+                    //it could also be a constructor
+                    else if (d instanceof IClassDefinition)
+                    {
+                        IClassDefinition classDef = (IClassDefinition) d;
+                        IFunctionDefinition constructorDef = classDef.getConstructor();
+                        if (constructorDef != null)
+                        {
+                            IASNode m = constructorDef.getNode();
+                            if (m != null)
+                            {
+                                // re-emit it to collect static initializer class references in usedNames
+                                getEmitter().stringifyNode(m);
+                            }
+                        }
+                    }
             	}
             }
         	getModel().inStaticInitializer = false;
-        	if ((ndef.isStatic() && !EmitterUtils.needsStaticInitializer(vnodeString, className)) || 
+        	if ((ndef.isStatic() && !EmitterUtils.needsStaticInitializer(vnodeString, className)) ||
         			(!ndef.isStatic() && EmitterUtils.isScalar(vnode)) ||
         			isPackageOrFileMember)
 	        {
@@ -154,15 +175,36 @@
 	            write(ASEmitterTokens.SPACE);
 	            writeToken(ASEmitterTokens.EQUAL);
 	            endMapping(node);
-                startMapping(vnode);
-	            write(vnodeString);
-                endMapping(vnode);
+                getEmitter().emitAssignmentCoercion(vnode, node.getVariableTypeNode().resolve(getProject()));
 	        }
 	        else if (ndef.isStatic() && EmitterUtils.needsStaticInitializer(vnodeString, className))
 	        {
 	        	hasComplexStaticInitializers = true;
 	        }
-        }        
+	        
+	        if (!isPackageOrFileMember  && !ndef.isStatic() && !EmitterUtils.isScalar(vnode)
+                    && getProject() instanceof RoyaleJSProject
+                    && ((RoyaleJSProject) getProject()).config != null
+                    && ((RoyaleJSProject) getProject()).config.getJsDefaultInitializers()
+            )
+	        {
+	            //this value will actually be initialized inside the constructor.
+                //but if default initializers is set, we define it on the prototype with null value first.
+	            //Why?: this needs to be defined on the prototype to support reflection
+                //otherwise the constructor initializers will create the new property value on 'this' and
+                //there is no runtime clue to separate what is 'dynamic' and what is 'inherited'
+                //these clues throughout the prototype chain are important for runtime identification
+                //of dynamic fields.
+                //runtime checks will only work accurately using this technique if the entire inheritance chain
+                //for the reflection target is compiled with default js initializers, because it permits
+                //inspection of the prototype chain to determine all the sealed members, and isolate them
+                //from whatever else is defined as 'own' properties on the instance (which can be assumed to be
+                // 'dynamic' properties).
+                write(ASEmitterTokens.SPACE);
+                writeToken(ASEmitterTokens.EQUAL);
+                write(ASEmitterTokens.NULL);
+            }
+        }
         if (vnode == null && def != null)
         {
             String defName = def.getQualifiedName();
@@ -197,12 +239,17 @@
                         write(ASEmitterTokens.SPACE);
                         writeToken(ASEmitterTokens.EQUAL);
                         write(IASKeywordConstants.FALSE);
+                        
+                    } else if (defName.equals("*")) {
+                        //setting the value to *undefined* is needed  to create the field
+                        //on the prototype - this is important for reflection purposes
+                        write(ASEmitterTokens.SPACE);
+                        writeToken(ASEmitterTokens.EQUAL);
+                        write(ASEmitterTokens.UNDEFINED);
                     }
-                    else if (!defName.equals("*"))
+                    else
                     {
-                        //type * is meant to default to undefined, so it
-                        //doesn't need to be initialized, but everything
-                        //else should default to null
+                        //everything else should default to null
                         write(ASEmitterTokens.SPACE);
                         writeToken(ASEmitterTokens.EQUAL);
                         write(IASKeywordConstants.NULL);
@@ -263,8 +310,8 @@
         	if (ndef.isStatic() && EmitterUtils.needsStaticInitializer(vnodeString, className) && !isPackageOrFileMember)
 	        {
                 writeNewline();
-                write(className
-                        + ASEmitterTokens.MEMBER_ACCESS.getToken());
+                write(className);
+                write(ASEmitterTokens.MEMBER_ACCESS.getToken());
                 write(node.getName());
 	
 	            if (node.getNodeID() == ASTNodeID.BindableVariableID && !node.isConst())
@@ -278,7 +325,7 @@
 	            write(vnodeString);
 	            write(ASEmitterTokens.SEMICOLON);
                 return true;
-	        }
+            }
         }
 
         return false;
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FunctionCallArgumentsEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FunctionCallArgumentsEmitter.java
index bca4c59..c92f189 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FunctionCallArgumentsEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FunctionCallArgumentsEmitter.java
@@ -21,10 +21,14 @@
 
 import org.apache.royale.compiler.codegen.ISubEmitter;
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
+import org.apache.royale.compiler.definitions.IDefinition;
+import org.apache.royale.compiler.definitions.IFunctionDefinition;
+import org.apache.royale.compiler.definitions.IParameterDefinition;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSSubEmitter;
 import org.apache.royale.compiler.tree.as.IContainerNode;
 import org.apache.royale.compiler.tree.as.IExpressionNode;
+import org.apache.royale.compiler.tree.as.IFunctionCallNode;
 
 public class FunctionCallArgumentsEmitter extends JSSubEmitter implements
         ISubEmitter<IContainerNode>
@@ -41,11 +45,38 @@
         write(ASEmitterTokens.PAREN_OPEN);
         endMapping(node);
 
+        IParameterDefinition[] paramDefs = null;
+        IFunctionCallNode functionCallNode = (IFunctionCallNode) node.getAncestorOfType(IFunctionCallNode.class);
+        if (functionCallNode != null)
+        {
+            IDefinition calledDef = functionCallNode.resolveCalledExpression(getProject());
+            if (calledDef instanceof IFunctionDefinition)
+            {
+                IFunctionDefinition functionDef = (IFunctionDefinition) calledDef;
+                paramDefs = functionDef.getParameters();
+            }
+        }
+
         int len = node.getChildCount();
         for (int i = 0; i < len; i++)
         {
             IExpressionNode argumentNode = (IExpressionNode) node.getChild(i);
-            getWalker().walk(argumentNode);
+            IDefinition paramTypeDef = null;
+            if (paramDefs != null && paramDefs.length > i)
+            {
+                IParameterDefinition paramDef = paramDefs[i];
+                if (paramDef.isRest())
+                {
+                    paramDef = null;
+                }
+                if (paramDef != null)
+                {
+                    paramTypeDef = paramDef.resolveType(getProject());
+                }
+            }
+
+            getEmitter().emitAssignmentCoercion(argumentNode, paramTypeDef);
+
             if (i < len - 1)
             {
                 //we're mapping the comma to the container, but we use the
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FunctionCallEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FunctionCallEmitter.java
index 776ebca..4de1d14 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FunctionCallEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FunctionCallEmitter.java
@@ -20,31 +20,29 @@
 package org.apache.royale.compiler.internal.codegen.js.jx;
 
 import org.apache.royale.compiler.codegen.IASGlobalFunctionConstants;
+import org.apache.royale.compiler.codegen.IDocEmitter;
 import org.apache.royale.compiler.codegen.ISubEmitter;
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
+import org.apache.royale.compiler.common.SourceLocation;
 import org.apache.royale.compiler.constants.IASLanguageConstants;
+import org.apache.royale.compiler.constants.IASLanguageConstants.BuiltinType;
 import org.apache.royale.compiler.definitions.IDefinition;
+import org.apache.royale.compiler.definitions.ITypeDefinition;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSSessionModel;
 import org.apache.royale.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleDocEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.utils.EmitterUtils;
-import org.apache.royale.compiler.internal.definitions.AppliedVectorDefinition;
-import org.apache.royale.compiler.internal.definitions.ClassDefinition;
-import org.apache.royale.compiler.internal.definitions.InterfaceDefinition;
+import org.apache.royale.compiler.internal.definitions.*;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
-import org.apache.royale.compiler.internal.tree.as.ContainerNode;
-import org.apache.royale.compiler.internal.tree.as.MemberAccessExpressionNode;
-import org.apache.royale.compiler.internal.tree.as.VectorLiteralNode;
+import org.apache.royale.compiler.internal.tree.as.*;
 import org.apache.royale.compiler.problems.TooFewFunctionParametersProblem;
 import org.apache.royale.compiler.problems.TooManyFunctionParametersProblem;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.ASTNodeID;
-import org.apache.royale.compiler.tree.as.IASNode;
-import org.apache.royale.compiler.tree.as.IContainerNode;
-import org.apache.royale.compiler.tree.as.IExpressionNode;
-import org.apache.royale.compiler.tree.as.IFunctionCallNode;
+import org.apache.royale.compiler.tree.as.*;
 import org.apache.royale.compiler.utils.NativeUtils;
 
 public class FunctionCallEmitter extends JSSubEmitter implements ISubEmitter<IFunctionCallNode>
@@ -60,12 +58,11 @@
     {
         // TODO (mschmalle) will remove this cast as more things get abstracted
         JSRoyaleEmitter fjs = (JSRoyaleEmitter) getEmitter();
-
         IASNode cnode = node.getChild(0);
 
         if (cnode.getNodeID() == ASTNodeID.MemberAccessExpressionID)
             cnode = cnode.getChild(0);
-
+        String postCallAppend = null;
         ASTNodeID id = cnode.getNodeID();
         if (id != ASTNodeID.SuperID)
         {
@@ -74,16 +71,45 @@
             def = nameNode.resolve(getProject());
 
             boolean isClassCast = false;
-
+            boolean wrapResolve = false;
             if (node.isNewExpression())
             {
-                if (!(node.getChild(1) instanceof VectorLiteralNode))
+                boolean omitNew = false;
+                if (nameNode instanceof IdentifierNode
+                        && (((IdentifierNode) nameNode).getName().equals(IASLanguageConstants.String)
+                        || ((IdentifierNode) nameNode).getName().equals(IASLanguageConstants.Boolean)
+                        || ((IdentifierNode) nameNode).getName().equals(IASLanguageConstants.Number)))
                 {
-                    if (def == null || !(def.getBaseName().equals(IASGlobalFunctionConstants._int) ||
-                    					 def.getBaseName().equals(IASGlobalFunctionConstants.uint) ||
-                    					 def instanceof AppliedVectorDefinition))
+                    omitNew = true;
+                }
+                
+                if (!((node.getChild(1) instanceof VectorLiteralNode)))
+                {
+                    if (!omitNew
+                            && ((def == null
+                                || !(def.getBaseName().equals(IASGlobalFunctionConstants._int) || def.getBaseName().equals(IASGlobalFunctionConstants.uint)))
+                                && !(def instanceof AppliedVectorDefinition && (
+                                        ((RoyaleJSProject) getProject()).config.getJsVectorEmulationClass()!= null
+                                        && ((RoyaleJSProject) getProject()).config.getJsVectorEmulationClass().equals("Array"))
+                                ))
+                        )
                     {
-	                    startMapping(node.getNewKeywordNode());
+	                    if (getProject() instanceof RoyaleJSProject
+                                && nameNode.resolveType(getProject()) != null
+                                && nameNode.resolveType(getProject()).getQualifiedName().equals("Class")) {
+        
+	                        wrapResolve = shouldResolveUncertain(nameNode, false);
+                            
+                            if (wrapResolve) {
+                                ((RoyaleJSProject) getProject()).needLanguage = true;
+                                getModel().needLanguage = true;
+                                write(JSRoyaleEmitterTokens.LANGUAGE_QNAME);
+                                write(ASEmitterTokens.MEMBER_ACCESS);
+                                write("resolveUncertain");
+                                write(ASEmitterTokens.PAREN_OPEN);
+                            }
+                        }
+                        startMapping(node.getNewKeywordNode());
 	                    writeToken(ASEmitterTokens.NEW);
 	                    endMapping(node.getNewKeywordNode());
                     }
@@ -91,7 +117,52 @@
                 else
                 {
                     VectorLiteralNode vectorLiteralNode = (VectorLiteralNode) node.getChild(1);
+                    String vectorEmulationClass = (((RoyaleJSProject)fjs.getWalker().getProject()).config.getJsVectorEmulationClass());
+                    SourceLocation mappingLocation;
+                    String elementClassName;
+                    IDefinition elementClass = (((AppliedVectorDefinition)def).resolveElementType(getWalker().getProject()));
+                    elementClassName = getEmitter().formatQualifiedName(elementClass.getQualifiedName());
+                    if (vectorEmulationClass != null)
+                    {
+                        if (!vectorEmulationClass.equals("Array")) {
+                            //Explanation:
+                            //this was how it was originally set up, but it assumes the constructor of the emulation
+                            //class can handle first argument being an Array or numeric value...
+                            writeToken(ASEmitterTokens.NEW);
+                            write(vectorEmulationClass);
+                            write(ASEmitterTokens.PAREN_OPEN);
+                        }// otherwise.... if 'Array' is the emulation class, then just use the literal content
+                    } else {
+                        //no 'new' output in this case, just coercion, so map from the start of 'new'
+                        startMapping(node);
+                        write(JSRoyaleEmitterTokens.SYNTH_VECTOR);
+                        write(ASEmitterTokens.PAREN_OPEN);
+                        write(ASEmitterTokens.SINGLE_QUOTE);
+                        //the element type of the Vector:
+                        write(elementClassName);
+                        write(ASEmitterTokens.SINGLE_QUOTE);
+                        write(ASEmitterTokens.PAREN_CLOSE);
+                        write(ASEmitterTokens.SQUARE_OPEN);
+                        write(ASEmitterTokens.SINGLE_QUOTE);
+                        write("coerce");
+                        write(ASEmitterTokens.SINGLE_QUOTE);
+                        write(ASEmitterTokens.SQUARE_CLOSE);
+                        mappingLocation = new SourceLocation(vectorLiteralNode.getCollectionTypeNode());
+                        mappingLocation.setEndColumn(mappingLocation.getEndColumn() + 1);
+                        endMapping(mappingLocation);
+                        write(ASEmitterTokens.PAREN_OPEN);
+                        if (getProject() instanceof RoyaleJSProject)
+                            ((RoyaleJSProject)getProject()).needLanguage = true;
+                        getEmitter().getModel().needLanguage = true;
+                      
+                    }
+                    mappingLocation = new SourceLocation(vectorLiteralNode.getContentsNode());
+                    if (mappingLocation.getColumn()>0) mappingLocation.setColumn(mappingLocation.getColumn() -1);
+                    mappingLocation.setEndColumn(mappingLocation.getColumn()+1);
+                    startMapping(mappingLocation);
                     write("[");
+                    
+                    endMapping(mappingLocation);
                     ContainerNode contentsNode = vectorLiteralNode.getContentsNode();
                     int len = contentsNode.getChildCount();
                     for (int i = 0; i < len; i++)
@@ -102,7 +173,25 @@
                             writeToken(ASEmitterTokens.COMMA);
                         }
                     }
+                    mappingLocation = new SourceLocation(vectorLiteralNode.getContentsNode());
+                    mappingLocation.setLine(vectorLiteralNode.getContentsNode().getEndLine());
+                    mappingLocation.setColumn(vectorLiteralNode.getContentsNode().getEndColumn());
+                    mappingLocation.setEndColumn(mappingLocation.getColumn() + 1);
+                    startMapping(mappingLocation);
                     write("]");
+                    endMapping(mappingLocation);
+                    if (vectorEmulationClass != null)
+                    {
+                        if (!vectorEmulationClass.equals("Array")) {
+                            writeToken(ASEmitterTokens.COMMA);
+                            write(ASEmitterTokens.SINGLE_QUOTE);
+                            write(elementClassName);
+                            write(ASEmitterTokens.SINGLE_QUOTE);
+                            write(ASEmitterTokens.PAREN_CLOSE);
+                        }
+                    } else {
+                        write(ASEmitterTokens.PAREN_CLOSE);
+                    }
                     return;
                 }
             }
@@ -110,12 +199,15 @@
             {
                 def = node.getNameNode().resolve(getProject());
 
-                isClassCast = (def instanceof ClassDefinition || def instanceof InterfaceDefinition)
+                isClassCast = def != null && (def instanceof ClassDefinition
+                        || def instanceof InterfaceDefinition
+                        || ( def instanceof VariableDefinition && ((VariableDefinition) def).resolveType(getProject()).getBaseName().equals("Class")))
                         && !(NativeUtils.isJSNative(def.getBaseName()))
                         && !def.getBaseName().equals(IASLanguageConstants.XML)
                         && !def.getBaseName().equals(IASLanguageConstants.XMLList);
+                
             }
-
+            
             if (node.isNewExpression())
             {
                 def = node.resolveCalledExpression(getProject());
@@ -156,16 +248,39 @@
                     if (nameNode.hasParenthesis())
                         write(ASEmitterTokens.PAREN_CLOSE);
                 }
-
-                if (def instanceof AppliedVectorDefinition)
+                if ( def instanceof AppliedVectorDefinition
+                        && (fjs.getWalker().getProject() instanceof RoyaleJSProject)
+                        && (((RoyaleJSProject)fjs.getWalker().getProject()).config.getJsVectorEmulationClass() != null))
                 {
-                	ContainerNode args = node.getArgumentsNode();
-                	if (args.getChildCount() == 0)
-                	{
-                    	getEmitter().emitArguments(node.getArgumentsNode());
-                	}
-                	else
-                	{
+                    ContainerNode args = node.getArgumentsNode();
+                    String vectorEmulationClass = ((RoyaleJSProject)fjs.getWalker().getProject()).config.getJsVectorEmulationClass();
+                    if (args.getChildCount() == 0)
+                    {
+                        if (vectorEmulationClass.equals("Array")) {
+                            write(ASEmitterTokens.SQUARE_OPEN);
+                            write(ASEmitterTokens.SQUARE_CLOSE);
+                        } else {
+                            write(ASEmitterTokens.PAREN_OPEN);
+                            write(ASEmitterTokens.SQUARE_OPEN);
+                            write(ASEmitterTokens.SQUARE_CLOSE);
+                            write(ASEmitterTokens.COMMA);
+                            write(ASEmitterTokens.SPACE);
+                            write(ASEmitterTokens.SINGLE_QUOTE);
+                            write(((AppliedVectorDefinition)def).resolveElementType(getWalker().getProject()).getQualifiedName());
+                            write(ASEmitterTokens.SINGLE_QUOTE);
+                            write(ASEmitterTokens.PAREN_CLOSE);
+                        }
+                    } else {
+                        if (vectorEmulationClass.equals("Array")) {
+                            if (getProject() instanceof RoyaleJSProject)
+                                ((RoyaleJSProject) getProject()).needLanguage = true;
+                            getEmitter().getModel().needLanguage = true;
+                            write(JSRoyaleEmitterTokens.LANGUAGE_QNAME);
+                            write(ASEmitterTokens.MEMBER_ACCESS);
+                            startMapping(node.getNameNode());
+                            write("arrayAsVector");
+                            endMapping(node.getNameNode());
+                        }
                         startMapping(node);
                         write(ASEmitterTokens.PAREN_OPEN);
                         endMapping(node);
@@ -173,13 +288,29 @@
                         write(ASEmitterTokens.COMMA);
                         write(ASEmitterTokens.SPACE);
                         write(ASEmitterTokens.SINGLE_QUOTE);
-                        write(((AppliedVectorDefinition)def).resolveElementType(getWalker().getProject()).getBaseName());
+                        write(((AppliedVectorDefinition) def).resolveElementType(getWalker().getProject()).getQualifiedName());
                         write(ASEmitterTokens.SINGLE_QUOTE);
+                        if (args.getChildCount() == 2 && !vectorEmulationClass.equals("Array")) {
+                            IASNode second = args.getChild(1);
+                            if (second instanceof IExpressionNode) {
+                                ITypeDefinition secondType =
+                                        ((IExpressionNode) second).resolveType(fjs.getWalker().getProject());
+                                if (fjs.getWalker().getProject().getBuiltinType(BuiltinType.BOOLEAN).equals(secondType)) {
+                                    write(ASEmitterTokens.COMMA);
+                                    write(ASEmitterTokens.SPACE);
+                                    getWalker().walk(second);
+                                }
+                            }
+                        }
                         write(ASEmitterTokens.PAREN_CLOSE);
-                	}
+                    }
+                } else {
+                    getEmitter().emitArguments(node.getArgumentsNode());
                 }
-                else
-                	getEmitter().emitArguments(node.getArgumentsNode());
+                //end wrap resolve
+                if (wrapResolve) {
+                    write(ASEmitterTokens.PAREN_CLOSE);
+                }
             }
             else if (!isClassCast)
             {
@@ -220,37 +351,100 @@
             		}
                     else if (def.getBaseName().equals("sort"))
                 	{
-                		if (def.getParent() != null &&
-                    		def.getParent().getQualifiedName().equals("Array"))
-                		{
-                			IExpressionNode args[] = node.getArgumentNodes();
-                			if (args.length > 0)
-                			{
-                                IExpressionNode optionsParamCheck = args.length == 1 ? args[0] : args[1];
-                                ICompilerProject project = this.getProject();
-                                IDefinition paramCheck = optionsParamCheck.resolveType(project);
-
-                                if (paramCheck.getBaseName().equals(IASLanguageConstants._int)
-                                    || paramCheck.getBaseName().equals(IASLanguageConstants.uint)
-                                    || paramCheck.getBaseName().equals(IASLanguageConstants.Number))
+                	    if (def.getParent() != null) {
+                	        if (def.getParent().getQualifiedName().equals("Array")
+                                || (node.getNameNode() instanceof MemberAccessExpressionNode
+                                    && (((MemberAccessExpressionNode) node.getNameNode()).getLeftOperandNode().resolveType(getProject()) instanceof AppliedVectorDefinition)
+                                    &&  getProject() instanceof RoyaleJSProject
+                                    && (((RoyaleJSProject)getProject()).config.getJsVectorEmulationClass() == null
+                                    || ((RoyaleJSProject)getProject()).config.getJsVectorEmulationClass().equals("Array"))))
+                	        {
+                                IExpressionNode args[] = node.getArgumentNodes();
+                                if (args.length > 0)
                                 {
-                                    //deal with specific numeric option argument variations
-                                    //either: Array.sort(option:uint) or Array.sort(compareFunction:Function, option:uint)
-                                    //use our Language sort implementation to support these actionscript-specific method signatures
-                                    if (project instanceof RoyaleJSProject)
-                                        ((RoyaleJSProject) project).needLanguage = true;
-                                    getEmitter().getModel().needLanguage = true;
-                                    write(JSRoyaleEmitterTokens.LANGUAGE_QNAME);
-                                    write(ASEmitterTokens.MEMBER_ACCESS);
-                                    write("sort");
-                                    IContainerNode newArgs = EmitterUtils.insertArgumentsBefore(node.getArgumentsNode(), cnode);
-                                    fjs.emitArguments(newArgs);
-                                    return;
+                                    IExpressionNode optionsParamCheck = args.length == 1 ? args[0] : args[1];
+                                    ICompilerProject project = this.getProject();
+                                    IDefinition paramCheck = optionsParamCheck.resolveType(project);
+            
+                                    if (paramCheck.getBaseName().equals(IASLanguageConstants._int)
+                                            || paramCheck.getBaseName().equals(IASLanguageConstants.uint)
+                                            || paramCheck.getBaseName().equals(IASLanguageConstants.Number))
+                                    {
+                                        //deal with specific numeric option argument variations
+                                        //either: Array.sort(option:uint) or Array.sort(compareFunction:Function, option:uint)
+                                        //use our Language sort implementation to support these actionscript-specific method signatures
+                                        if (project instanceof RoyaleJSProject)
+                                            ((RoyaleJSProject) project).needLanguage = true;
+                                        getEmitter().getModel().needLanguage = true;
+                                        write(JSRoyaleEmitterTokens.LANGUAGE_QNAME);
+                                        write(ASEmitterTokens.MEMBER_ACCESS);
+                                        write("sort");
+                                        IContainerNode newArgs = EmitterUtils.insertArgumentsBefore(node.getArgumentsNode(), cnode);
+                                        fjs.emitArguments(newArgs);
+                                        return;
+                                    }
                                 }
-                			}
-            			}
+                            }
+                        }
+                	    
             		}
+                    else if ((def.getBaseName().equals("insertAt")
+                                || def.getBaseName().equals("removeAt"))
+                                &&  def.getParent() instanceof AppliedVectorDefinition
+                                && ((getProject() instanceof RoyaleJSProject) && (
+                                    ((RoyaleJSProject)getProject()).config.getJsVectorEmulationClass() == null
+                                    || ((RoyaleJSProject)getProject()).config.getJsVectorEmulationClass().equals("Array")))
+                           ) {
 
+                            if ((((RoyaleJSProject)getProject()).config.getJsVectorEmulationClass() != null)
+                                && ((RoyaleJSProject)getProject()).config.getJsVectorEmulationClass().equals("Array")) {
+                                //use a similar approach to regular 'Array' insertAt/removeAt
+                                //for Array Vector emulation only (not for other custom classes)
+                                //replace the insertAt/removeAt method with 'splice'
+                                IdentifierNode splice = new IdentifierNode("splice");
+                                splice.setSourceLocation(((MemberAccessExpressionNode)node.getNameNode()).getRightOperandNode());
+                                splice.setParent((MemberAccessExpressionNode)node.getNameNode());
+                                ((MemberAccessExpressionNode)node.getNameNode()).setRightOperandNode(splice);
+                                NumericLiteralNode spliceArg;
+                                if (def.getBaseName().equals("insertAt")) {
+                                    //insertAt
+                                    spliceArg = new NumericLiteralNode("0");
+                                    //This works like 'insertAt' itself, pushing the insertee to 3rd position (correct position):
+                                    node.getArgumentsNode().addChild(spliceArg, 1);
+                                } else {
+                                    //removeAt
+                                    spliceArg = new NumericLiteralNode("1");
+                                    node.getArgumentsNode().addChild(spliceArg, 1);
+                                    postCallAppend = "[0]";
+                                }
+                            } else {
+                                //default Vector implementation
+                                //unlike Array implementation of these methods, the synthetic Vector implementation supports these methods at runtime,
+                                //and they behave differently with fixed length vectors compared to the native 'splice' method output which is used to
+                                //support them in Array, however they are not protected from GCL renaming in release builds by any actual class definition,
+                                //so we explicitly 'protect' them here by using DynamicAccess instead of MemberAccess
+                                ExpressionNodeBase leftSide = (ExpressionNodeBase)(((BinaryOperatorNodeBase) (node.getNameNode())).getLeftOperandNode());
+                                LiteralNode dynamicName = new LiteralNode(ILiteralNode.LiteralType.STRING, "'" + def.getBaseName() + "'");
+                                dynamicName.setSourceLocation(((BinaryOperatorNodeBase) (node.getNameNode())).getRightOperandNode());
+                                DynamicAccessNode replacement = new DynamicAccessNode(leftSide);
+                                leftSide.setParent(replacement);
+                                replacement.setSourceLocation(node.getNameNode());
+                                replacement.setRightOperandNode(dynamicName);
+                                dynamicName.setParent(replacement);
+    
+                                FunctionCallNode replacer = new FunctionCallNode(replacement)   ;
+                                replacement.setParent(replacer);
+                                IExpressionNode[] args = node.getArgumentNodes();
+                                for (IExpressionNode arg : args) {
+                                    replacer.getArgumentsNode().addItem((NodeBase) arg);
+                                }
+                                replacer.getArgumentsNode().setParent(replacer);
+                                replacer.getArgumentsNode().setSourceLocation(node.getArgumentsNode());
+                                replacer.setParent((NodeBase) node.getParent());
+                                //swap it out
+                                node = replacer;
+                            }
+                    }
                     else if (def instanceof AppliedVectorDefinition)
                     {
                         IExpressionNode[] argumentNodes = node.getArgumentNodes();
@@ -265,9 +459,54 @@
                     	}
                     	else
                     	{
-                            IExpressionNode argumentNode = argumentNodes[0];
-                            getWalker().walk(argumentNode);
-                            write(".slice()");
+                            String elementClassName = getEmitter().formatQualifiedName(((TypedExpressionNode)nameNode).getTypeNode().resolve(getProject()).getQualifiedName());
+                    	    if (getProject() instanceof RoyaleJSProject
+                                && ((RoyaleJSProject) getProject()).config.getJsVectorEmulationClass()!= null) {
+                    	        String vectorEmulationClass = ((RoyaleJSProject) getProject()).config.getJsVectorEmulationClass();
+                    	        if (vectorEmulationClass.equals("Array")) {
+                    	            //just do a slice copy of the array which is the first argument
+                                    getWalker().walk(node.getArgumentsNode().getChild(0));
+                                    write(ASEmitterTokens.MEMBER_ACCESS);
+                                    write("slice");
+                                    write(ASEmitterTokens.PAREN_OPEN);
+                                    write(ASEmitterTokens.PAREN_CLOSE);
+                                } else {
+                    	            //assume the emulation class can handle an array or numeric value for first constructor arg...
+                                    writeToken(ASEmitterTokens.NEW);
+                                    startMapping(node.getNameNode());
+                                    write(vectorEmulationClass);
+                                    endMapping(node.getNameNode());
+                                    write(ASEmitterTokens.PAREN_OPEN);
+                                    getWalker().walk(node.getArgumentsNode().getChild(0));
+                                    writeToken(ASEmitterTokens.COMMA);
+                                    write(ASEmitterTokens.SINGLE_QUOTE);
+                                    //the element type of the Vector:
+                                    write(elementClassName);
+                                    write(ASEmitterTokens.SINGLE_QUOTE);
+                                    write(ASEmitterTokens.PAREN_CLOSE);
+                                }
+                            } else {
+                    	        //default Vector implementation
+                                startMapping(node.getNameNode());
+                                write(JSRoyaleEmitterTokens.SYNTH_VECTOR);
+                                write(ASEmitterTokens.PAREN_OPEN);
+                                write(ASEmitterTokens.SINGLE_QUOTE);
+                                //the element type of the Vector:
+                                write(elementClassName);
+                                write(ASEmitterTokens.SINGLE_QUOTE);
+                                write(ASEmitterTokens.PAREN_CLOSE);
+                                write(ASEmitterTokens.SQUARE_OPEN);
+                                write(ASEmitterTokens.SINGLE_QUOTE);
+                                write("coerce");
+                                write(ASEmitterTokens.SINGLE_QUOTE);
+                                write(ASEmitterTokens.SQUARE_CLOSE);
+                                endMapping(node.getNameNode());
+        
+                                getEmitter().emitArguments(node.getArgumentsNode());
+                                if (getProject() instanceof RoyaleJSProject)
+                                    ((RoyaleJSProject)getProject()).needLanguage = true;
+                                getEmitter().getModel().needLanguage = true;
+                            }
                         }
                         return;
                     }
@@ -277,6 +516,44 @@
                         getEmitter().emitArguments(node.getArgumentsNode());
                     	return;
                     }
+                    else if (def.getBaseName().equals(IASLanguageConstants.XMLList))
+                    {
+                        write("XMLList.conversion");
+                        getEmitter().emitArguments(node.getArgumentsNode());
+                        return;
+                    }
+                    else if (def.getQualifiedName().equals(IASLanguageConstants.Object)) {
+                        //'resolveUncertain' always output here
+                        //unless a) there are no arguments
+                        //or b) it is *explicitly* suppressed for 'Object'
+                        if (node.getArgumentNodes().length > 0) {
+                            if (shouldResolveUncertain(nameNode, true)) {
+                                wrapResolve = true;
+                                ((RoyaleJSProject) getProject()).needLanguage = true;
+                                getModel().needLanguage = true;
+                                write(JSRoyaleEmitterTokens.LANGUAGE_QNAME);
+                                write(ASEmitterTokens.MEMBER_ACCESS);
+                                write("resolveUncertain");
+                                write(ASEmitterTokens.PAREN_OPEN);
+                            }
+                        }
+                    }
+                    else if (nameNode.getNodeID() == ASTNodeID.NamespaceAccessExpressionID && def instanceof FunctionDefinition)
+                    {
+                    	if (fjs.isCustomNamespace((FunctionDefinition)def))
+                    	{
+                    		write(ASEmitterTokens.THIS);
+                    		NamespaceIdentifierNode nin = (NamespaceIdentifierNode)nameNode.getChild(0);
+                    		NamespaceDefinition nsDef = (NamespaceDefinition)nin.resolve(getProject());
+                    		IdentifierNode idNode = (IdentifierNode)nameNode.getChild(1);
+                    		String propName = idNode.getName();
+                			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names
+                			String s = nsDef.getURI();
+                			write(JSRoyaleEmitter.formatNamespacedProperty(s, propName, true));
+                            getEmitter().emitArguments(node.getArgumentsNode());
+                            return;
+                    	}
+                    }
                 }
                 else if (nameNode.getNodeID() == ASTNodeID.MemberAccessExpressionID && ((JSRoyaleEmitter)getEmitter()).isProxy(((MemberAccessExpressionNode)nameNode).getLeftOperandNode()) && def == null)
                 {
@@ -301,6 +578,14 @@
             	getWalker().walk(node.getNameNode());
 
                 getEmitter().emitArguments(node.getArgumentsNode());
+    
+                if (postCallAppend != null) {
+                    write(postCallAppend);
+                }
+                //end wrap resolve
+                if (wrapResolve) {
+                    write(ASEmitterTokens.PAREN_CLOSE);
+                }
             }
             else //function-style cast
             {
@@ -312,5 +597,31 @@
             fjs.emitSuperCall(node, JSSessionModel.SUPER_FUNCTION_CALL);
         }
     }
+    
+    
+    private boolean shouldResolveUncertain(IExpressionNode nameNode, boolean forceExplicit) {
+        //default if not avoided globally
+        boolean should = ((RoyaleJSProject)getProject()).config.getJsResolveUncertain();
+        //just in case:
+        if (!(getProject() instanceof RoyaleJSProject)) return false;
+
+        IDocEmitter docEmitter = getEmitter().getDocEmitter();
+        if (docEmitter instanceof JSRoyaleDocEmitter)
+        {
+            JSRoyaleDocEmitter royaleDocEmitter = (JSRoyaleDocEmitter) docEmitter;
+            //look for local boolean toggle, unless forceExplicit is set
+            boolean suppress = !forceExplicit && royaleDocEmitter.getLocalSettingAsBoolean(
+                    JSRoyaleEmitterTokens.SUPPRESS_RESOLVE_UNCERTAIN, !should);
+            //if it is still on, look for sepcific/named 'off' setting based on name node
+            if (!suppress && nameNode !=null) {
+                //check to suppress for indvidual named node
+                if (nameNode instanceof IdentifierNode) {
+                    suppress = royaleDocEmitter.getLocalSettingIncludesString(JSRoyaleEmitterTokens.SUPPRESS_RESOLVE_UNCERTAIN, ((IdentifierNode) nameNode).getName());
+                }
+            }
+            should = !suppress;
+        }
+        return should;
+    }
 
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java
index 3874676..f6363ea 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java
@@ -19,9 +19,12 @@
 
 package org.apache.royale.compiler.internal.codegen.js.jx;
 
+import org.apache.royale.abc.ABCConstants;
 import org.apache.royale.abc.semantics.Namespace;
 import org.apache.royale.compiler.codegen.ISubEmitter;
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
+import org.apache.royale.compiler.constants.IASLanguageConstants;
+import org.apache.royale.compiler.definitions.IConstantDefinition;
 import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.definitions.IFunctionDefinition;
 import org.apache.royale.compiler.definitions.IFunctionDefinition.FunctionClassification;
@@ -34,17 +37,16 @@
 import org.apache.royale.compiler.internal.codegen.js.JSSubEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter;
 import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
+import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.utils.EmitterUtils;
-import org.apache.royale.compiler.internal.definitions.AccessorDefinition;
-import org.apache.royale.compiler.internal.definitions.FunctionDefinition;
-import org.apache.royale.compiler.internal.definitions.TypeDefinitionBase;
+import org.apache.royale.compiler.internal.definitions.*;
+import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
+import org.apache.royale.compiler.internal.tree.as.BinaryOperatorAssignmentNode;
+import org.apache.royale.compiler.internal.tree.as.BinaryOperatorDivisionAssignmentNode;
+import org.apache.royale.compiler.internal.tree.as.MemberAccessExpressionNode;
 import org.apache.royale.compiler.internal.tree.as.NonResolvingIdentifierNode;
 import org.apache.royale.compiler.tree.ASTNodeID;
-import org.apache.royale.compiler.tree.as.IASNode;
-import org.apache.royale.compiler.tree.as.IFunctionNode;
-import org.apache.royale.compiler.tree.as.IFunctionObjectNode;
-import org.apache.royale.compiler.tree.as.IIdentifierNode;
-import org.apache.royale.compiler.tree.as.IMemberAccessExpressionNode;
+import org.apache.royale.compiler.tree.as.*;
 import org.apache.royale.compiler.utils.NativeUtils;
 
 public class IdentifierEmitter extends JSSubEmitter implements
@@ -78,12 +80,43 @@
                 && !identifierIsAccessorFunction;
         boolean emitName = true;
     	JSRoyaleEmitter fjs = (JSRoyaleEmitter)getEmitter();
+        RoyaleJSProject project = (RoyaleJSProject)getWalker().getProject();
     	boolean isCustomNamespace = false;
     	boolean isStatic = nodeDef != null && nodeDef.isStatic();
         if (nodeDef instanceof FunctionDefinition &&
           	  fjs.isCustomNamespace((FunctionDefinition)nodeDef))
-          	isCustomNamespace = true;
+              isCustomNamespace = true;
 
+        if (isStatic
+                && nodeDef instanceof IConstantDefinition
+                && project != null && project.config != null
+                && project.config.getInlineConstants())
+        {
+            IConstantDefinition constDef = (IConstantDefinition) nodeDef;
+            Object initialValue = constDef.resolveInitialValue(project);
+            if (initialValue != null)
+            {
+                startMapping(parentNode);
+                if(initialValue instanceof String)
+                {
+                    write("\"" + initialValue + "\"");
+                }
+                else if(initialValue == ABCConstants.UNDEFINED_VALUE)
+                {
+                    write(IASLanguageConstants.UNDEFINED);
+                }
+                else if(initialValue == ABCConstants.NULL_VALUE)
+                {
+                    write(IASLanguageConstants.NULL);
+                }
+                else
+                {
+                    write(initialValue.toString());
+                }
+                endMapping(parentNode);
+                return;
+            }
+        }
         if (isStatic)
         {
             String sname = nodeDef.getParent().getQualifiedName();
@@ -238,14 +271,14 @@
                 {
                 	Namespace ns = (Namespace)((INamespaceResolvedReference)((FunctionDefinition)nodeDef).getNamespaceReference()).resolveAETNamespace(getProject());
                 	INamespaceDefinition nsDef = ((FunctionDefinition)nodeDef).getNamespaceReference().resolveNamespaceReference(getProject());
-        			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
+        			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names
                 	String nsName = ns.getName();
-                	write("[\"" + nsName + "::" + node.getName() + "\"]");
+                	write(JSRoyaleEmitter.formatNamespacedProperty(nsName, node.getName(), true));
                 }
                 else
                 {
             		String qname = node.getName();
-                	if (nodeDef != null && (!(nodeDef instanceof IParameterDefinition)) && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
+                	if (nodeDef != null && !isStatic && (!(nodeDef instanceof IParameterDefinition)) && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
                 		qname = getEmitter().formatPrivateName(nodeDef.getParent().getQualifiedName(), qname);
             		write(qname);
                 }
@@ -310,36 +343,47 @@
                     else if (isCustomNamespace)
                     {
                     	String ns = ((INamespaceResolvedReference)((FunctionDefinition)nodeDef).getNamespaceReference()).resolveAETNamespace(getProject()).getName();
-                    	write("[\"" + ns + "::" + qname + "\"]");
+                    	write(JSRoyaleEmitter.formatNamespacedProperty(ns, qname, true));
                     }
                     else if (identifierIsAccessorFunction && isStatic)
                     {
-                    	write("[\"" +node.getName() + "\"]");                    	
+                    	write("[\"" +node.getName() + "\"]");
                     }
                 	else
                 	{
                 		qname = node.getName();
-                    	if (nodeDef != null && (!(nodeDef instanceof IParameterDefinition)) && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
+                    	if (nodeDef != null && !isStatic && (nodeDef.getParent() instanceof ClassDefinition) && (!(nodeDef instanceof IParameterDefinition)) && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
                     		qname = getEmitter().formatPrivateName(nodeDef.getParent().getQualifiedName(), qname);
-                		write(qname);
+                    	write(qname);
                 	}
                 }
                 else if (isPackageOrFileMember)
                     write(getEmitter().formatQualifiedName(qname));
                 else if (nodeDef instanceof TypeDefinitionBase)
-                    write(getEmitter().formatQualifiedName(qname));
+                {
+                    if (NativeUtils.isSyntheticJSType(qname) && !(parentNode instanceof IFunctionCallNode)) {
+                        getEmitter().getModel().needLanguage = true;
+                        write(JSRoyaleEmitterTokens.SYNTH_TYPE);
+                        write(ASEmitterTokens.PAREN_OPEN);
+                        write(ASEmitterTokens.SINGLE_QUOTE);
+                        write(getEmitter().formatQualifiedName(qname));
+                        write(ASEmitterTokens.SINGLE_QUOTE);
+                        write(ASEmitterTokens.PAREN_CLOSE);
+                    }
+                    else write(getEmitter().formatQualifiedName(qname));
+                }
                 else if (isCustomNamespace)
                 {
                 	String ns = ((INamespaceResolvedReference)((FunctionDefinition)nodeDef).getNamespaceReference()).resolveAETNamespace(getProject()).getName();
-                	write("[\"" + ns + "::" + qname + "\"]");
+                	write(JSRoyaleEmitter.formatNamespacedProperty(ns, qname, true));
                 }
                 else if (identifierIsAccessorFunction && isStatic)
                 {
-                	write("[\"" + qname + "\"]");                    	
+                	write("[\"" + qname + "\"]");
                 }
-                else 
+                else
                 {
-                	if (nodeDef != null && (!(nodeDef instanceof IParameterDefinition)) && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
+                	if (nodeDef != null && !isStatic && (nodeDef.getParent() instanceof ClassDefinition) && (!(nodeDef instanceof IParameterDefinition)) && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
                 		qname = getEmitter().formatPrivateName(nodeDef.getParent().getQualifiedName(), qname);
                     write(qname);
                 }
@@ -352,7 +396,7 @@
                 write("child('");
                 write(node.getName());
                 write("')");
-                endMapping(node);            	
+                endMapping(node);
             }
             else
             {
@@ -362,5 +406,7 @@
             }
         }
     }
+    
+    
 
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IfEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IfEmitter.java
index 74ca31c..a5c987b 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IfEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IfEmitter.java
@@ -68,6 +68,13 @@
         {
             emitElse(elseNode);
         }
+        // if no actual work is done in the if clause, and there are no else/elseif causes
+        // emit an empty block.  Closure doesn't like a plain semicolon.
+        if (nodes.length == 0 && elseNode == null && conditional.getChild(1).getChildCount() == 0)
+        {
+        	write(ASEmitterTokens.BLOCK_OPEN);
+        	writeNewline(ASEmitterTokens.BLOCK_CLOSE);
+        }
         
     }
 
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/InterfaceEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/InterfaceEmitter.java
index 0221afc..eb8f079 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/InterfaceEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/InterfaceEmitter.java
@@ -26,9 +26,11 @@
 import org.apache.royale.compiler.internal.codegen.js.JSDocEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogDocEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleDocEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens;
+import org.apache.royale.compiler.internal.tree.as.TypedExpressionNode;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IAccessorNode;
@@ -114,6 +116,14 @@
                 	ITypeDefinition typeDef = typeNode.resolveType(project);
                 	String packageName = typeDef.getPackageName();
                 	packageName = project.getActualPackageName(packageName);
+                    if (typeNode instanceof TypedExpressionNode) {
+                        propType = "Vector.<" +
+                                JSGoogDocEmitter.convertASTypeToJSType(
+                                        ((TypedExpressionNode)typeNode).getTypeNode().resolveType(project).getQualifiedName(),
+                                        "")
+                                +">";
+                        packageName = "";
+                    }
                     write(JSDocEmitterTokens.JSDOC_OPEN);
                     write(ASEmitterTokens.SPACE);
                     fjs.getDocEmitter().emitType(propType, packageName);
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/LiteralContainerEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/LiteralContainerEmitter.java
index 45fc4e8..c42c211 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/LiteralContainerEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/LiteralContainerEmitter.java
@@ -23,6 +23,8 @@
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.royale.compiler.internal.tree.as.LiteralNode;
+import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IASNode;
 import org.apache.royale.compiler.tree.as.IContainerNode;
 import org.apache.royale.compiler.tree.as.ILiteralContainerNode;
@@ -42,6 +44,7 @@
         final IContainerNode.ContainerType type = cnode.getContainerType();
         String preFix = null;
         String postFix = null;
+        boolean isXMLList = node.getNodeID() == ASTNodeID.XMLListContentID;
 
         if (type == IContainerNode.ContainerType.BRACES)
         {
@@ -70,22 +73,50 @@
             endMapping(node);
         }
 
+        if (isXMLList)
+        {
+        	write("new XMLList(\"");
+        }
         final int len = cnode.getChildCount();
         for (int i = 0; i < len; i++)
         {
             IASNode child = cnode.getChild(i);
-            getWalker().walk(child);
-            if (i < len - 1)
+            if (isXMLList)
             {
-                //we're mapping the comma to the literal container, but we fill
-                //the space between the current child and the next because we
-                //don't know exactly where the comma appears in ActionScript
-                startMapping(node, child);
-                writeToken(ASEmitterTokens.COMMA);
-                endMapping(node);
+            	if (child instanceof LiteralNode)
+            	{
+            		String value = ((LiteralNode)child).getValue(true);
+            		value = value.replace("\"", "\\\"");
+            		value = value.replace("\r", "");
+            		value = value.replace("\n", "\\n");
+            		// skip the wrapping empty nodes.  XMLList
+            		// is expecting illegal xml (a sequence of children nodes
+            		// and will wrap it
+            		// in containing nodes
+            		if (value.contentEquals("<>"))
+            			continue;
+            		else if (value.contentEquals("</>"))
+            			continue;
+            		write(value);
+            	}
+            }
+            else
+            {
+	            getWalker().walk(child);
+	            if (i < len - 1)
+	            {
+	                //we're mapping the comma to the literal container, but we fill
+	                //the space between the current child and the next because we
+	                //don't know exactly where the comma appears in ActionScript
+	                startMapping(node, child);
+	                writeToken(ASEmitterTokens.COMMA);
+	                endMapping(node);
+	            }
             }
         }
-
+        if (isXMLList)
+        	write("\")");
+        
         if (postFix != null)
         {
             startMapping(node, node.getEndLine(), node.getEndColumn() - postFix.length());
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/LiteralEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/LiteralEmitter.java
index 6c79341..939f498 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/LiteralEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/LiteralEmitter.java
@@ -107,6 +107,7 @@
 	                            if (child instanceof LiteralNode)
 	                            {
 	                                s = ((LiteralNode)child).getValue(true);
+	                                s = s.replace("\n", "");
 	                                if (s.contains("'"))
 	                                    sb.append("\"" + s + "\"");
 	                                else
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MemberAccessEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
index e74820c..d6e5ccb 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
@@ -21,11 +21,16 @@
 
 import org.apache.royale.compiler.codegen.ISubEmitter;
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
+import org.apache.royale.compiler.constants.IASKeywordConstants;
 import org.apache.royale.compiler.constants.IASLanguageConstants;
+import org.apache.royale.compiler.constants.INamespaceConstants;
 import org.apache.royale.compiler.definitions.IDefinition;
+import org.apache.royale.compiler.definitions.INamespaceDefinition;
+import org.apache.royale.compiler.definitions.IPackageDefinition;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleDocEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
@@ -33,19 +38,10 @@
 import org.apache.royale.compiler.internal.definitions.AccessorDefinition;
 import org.apache.royale.compiler.internal.definitions.FunctionDefinition;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
-import org.apache.royale.compiler.internal.tree.as.DynamicAccessNode;
-import org.apache.royale.compiler.internal.tree.as.FunctionCallNode;
-import org.apache.royale.compiler.internal.tree.as.GetterNode;
-import org.apache.royale.compiler.internal.tree.as.IdentifierNode;
-import org.apache.royale.compiler.internal.tree.as.MemberAccessExpressionNode;
-import org.apache.royale.compiler.internal.tree.as.NamespaceAccessExpressionNode;
+import org.apache.royale.compiler.internal.tree.as.*;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.ASTNodeID;
-import org.apache.royale.compiler.tree.as.IASNode;
-import org.apache.royale.compiler.tree.as.IExpressionNode;
-import org.apache.royale.compiler.tree.as.IIdentifierNode;
-import org.apache.royale.compiler.tree.as.ILanguageIdentifierNode;
-import org.apache.royale.compiler.tree.as.IMemberAccessExpressionNode;
+import org.apache.royale.compiler.tree.as.*;
 import org.apache.royale.compiler.tree.as.IOperatorNode.OperatorType;
 import org.apache.royale.compiler.utils.ASNodeUtils;
 
@@ -102,30 +98,69 @@
         							rightNode.getNodeID() != ASTNodeID.Op_AtID &&
         							!((rightNode.getNodeID() == ASTNodeID.ArrayIndexExpressionID) && 
         									(((DynamicAccessNode)rightNode).getLeftOperandNode().getNodeID() == ASTNodeID.Op_AtID));
-        		if (descendant || child)
-	        	{
-	        		writeLeftSide(node, leftNode, rightNode);
-	        		if (descendant)
-	        			write(".descendants('");
-	        		if (child)
-	        			write(".child('");	        			
-	        		String s = fjs.stringifyNode(rightNode);
-	        		int dot = s.indexOf('.');
-	        		if (dot != -1)
-	        		{
-	        			String name = s.substring(0, dot);
-	        			String afterDot = s.substring(dot);
-	        			write(name);
-	        			write("')");
-	        			write(afterDot);
-	        		}
-	        		else
-	        		{
-	        			write(s);
-	        			write("')");
-	        		}
-	        		return;
-	        	}
+        		if (descendant || child) {
+					writeLeftSide(node, leftNode, rightNode);
+					if (descendant)
+						write(".descendants(");
+					if (child)
+						write(".child(");
+					String closeMethodCall = "')";
+					String s = "";
+					if (rightNode instanceof INamespaceAccessExpressionNode) {
+						NamespaceIdentifierNode namespaceIdentifierNode = (NamespaceIdentifierNode) ((INamespaceAccessExpressionNode) rightNode).getLeftOperandNode();
+						IDefinition nsDef =  namespaceIdentifierNode.resolve(getProject());
+						if (nsDef instanceof INamespaceDefinition
+								&& ((INamespaceDefinition)nsDef).getNamespaceClassification().equals(INamespaceDefinition.NamespaceClassification.LANGUAGE)) {
+							//deal with built-ins
+							String name = ((NamespaceIdentifierNode) ((INamespaceAccessExpressionNode) rightNode).getLeftOperandNode()).getName();
+							if (name.equals(INamespaceConstants.ANY)) {
+								//let the internal support within 'QName' class deal with it
+								write("new QName('*', '");
+								//only stringify the right node at the next step (it is the localName part)
+								rightNode = ((INamespaceAccessExpressionNode) rightNode).getRightOperandNode();
+								closeMethodCall = "'))";
+							} else if (name.equals(IASKeywordConstants.PUBLIC)
+									|| name.equals(IASKeywordConstants.PROTECTED)) {
+								//@todo check this, but both public and protected appear to have the effect of skipping the namespace part in swf, so just use default namespace
+								write("/* as3 " + name + " */ '");
+								//skip the namespace to just output the name
+								rightNode = ((INamespaceAccessExpressionNode) rightNode).getRightOperandNode();
+							} else {
+								//this is an unlikely condition, but do something that should give same results as swf...
+								//private, internal namespaces used in an XML context (I don't think this makes sense)
+								//@todo check this, but it seems like it should never match anything in a valid XML query
+								write("new QName('");
+								//provide an 'unlikely' 'uri':
+								write("_as3Lang_" + fjs.stringifyNode(namespaceIdentifierNode));
+								write(s + "', '");
+								//only stringify the right node at the next step (it is the localName part)
+								rightNode = ((INamespaceAccessExpressionNode) rightNode).getRightOperandNode();
+								closeMethodCall = "'))";
+							}
+						} else {
+							write("new QName(");
+							s = fjs.stringifyNode(namespaceIdentifierNode);
+							write(s + ", '");
+							//only stringify the right node at the next step (it is the localName part)
+							rightNode = ((INamespaceAccessExpressionNode) rightNode).getRightOperandNode();
+							closeMethodCall = "'))";
+						}
+					} else write("'"); //normal string name for child
+			
+					s = fjs.stringifyNode(rightNode);
+					int dot = s.indexOf('.');
+					if (dot != -1) {
+						String name = s.substring(0, dot);
+						String afterDot = s.substring(dot);
+						write(name);
+						write(closeMethodCall);
+						write(afterDot);
+					} else {
+						write(s);
+						write(closeMethodCall);
+					}
+					return;
+				}
         	}
         	else if (isProxy)
         	{
@@ -177,10 +212,18 @@
         		write(r.getName());
         		write(ASEmitterTokens.SINGLE_QUOTE);
         		write(ASEmitterTokens.PAREN_CLOSE);
+        		write(".objectAccessFormat()");
         		write(ASEmitterTokens.SQUARE_CLOSE);
         		return;
         	}
         }
+		else if(def.getParent() instanceof IPackageDefinition)
+		{
+			//this is a fully qualified name, and we should output it directly
+			//because we don't want it to be treated as dynamic access
+			write(fjs.formatQualifiedName(def.getQualifiedName()));
+			return;
+		}
         else if (def.getParent() != null &&
         		def.getParent().getQualifiedName().equals("Array"))
         {
@@ -199,6 +242,32 @@
         }
     	else if (rightNode instanceof NamespaceAccessExpressionNode)
     	{
+			boolean isStatic = false;
+			if (def != null && def.isStatic())
+				isStatic = true;
+			boolean needClosure = false;
+			if (def instanceof FunctionDefinition && (!(def instanceof AccessorDefinition))
+					&& !def.getBaseName().equals("constructor")) // don't wrap references to obj.constructor
+			{
+				IASNode parentNode = node.getParent();
+				if (parentNode != null)
+				{
+					ASTNodeID parentNodeId = parentNode.getNodeID();
+					// we need a closure if this MAE is the top-level in a chain
+					// of MAE and not in a function call.
+					needClosure = !isStatic && parentNodeId != ASTNodeID.FunctionCallID &&
+								parentNodeId != ASTNodeID.MemberAccessExpressionID &&
+								parentNodeId != ASTNodeID.ArrayIndexExpressionID;
+				}
+			}
+			
+			if (needClosure
+					&& getEmitter().getDocEmitter() instanceof JSRoyaleDocEmitter
+					&& ((JSRoyaleDocEmitter)getEmitter().getDocEmitter()).getSuppressClosure())
+				needClosure = false;
+        	if (needClosure)
+        		getEmitter().emitClosureStart();
+
     		NamespaceAccessExpressionNode naen = (NamespaceAccessExpressionNode)rightNode;
     		IDefinition d = naen.getLeftOperandNode().resolve(getProject());
     		IdentifierNode r = (IdentifierNode)(naen.getRightOperandNode());
@@ -218,6 +287,7 @@
 	    		write(r.getName());
 	    		write(ASEmitterTokens.SINGLE_QUOTE);
 	    		write(ASEmitterTokens.PAREN_CLOSE);
+        		write(".objectAccessFormat()");
 	    		write(ASEmitterTokens.SQUARE_CLOSE);
     		}
     		else
@@ -225,8 +295,19 @@
                 write(node.getOperator().getOperatorText());
 	    		write(r.getName());    			
     		}
+        
+			if (needClosure)
+			{
+				write(ASEmitterTokens.COMMA);
+				write(ASEmitterTokens.SPACE);
+				if (leftNode.getNodeID() == ASTNodeID.SuperID)
+					write(ASEmitterTokens.THIS);
+				else
+					writeLeftSide(node, leftNode, rightNode);
+				getEmitter().emitClosureEnd(leftNode, def);
+			}
     		return;
-    	}
+		}
         boolean isCustomNamespace = false;
         if (def instanceof FunctionDefinition && node.getOperator() == OperatorType.MEMBER_ACCESS)
         	isCustomNamespace = fjs.isCustomNamespace((FunctionDefinition)def);
@@ -246,6 +327,11 @@
 				needClosure = !isStatic && parentNodeId != ASTNodeID.FunctionCallID &&
 							parentNodeId != ASTNodeID.MemberAccessExpressionID &&
 							parentNodeId != ASTNodeID.ArrayIndexExpressionID;
+		
+				if (needClosure
+						&& getEmitter().getDocEmitter() instanceof JSRoyaleDocEmitter
+						&& ((JSRoyaleDocEmitter)getEmitter().getDocEmitter()).getSuppressClosure())
+					needClosure = false;
         		
         	}
         }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MethodEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MethodEmitter.java
index aad1184..0fc7b0b 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MethodEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MethodEmitter.java
@@ -108,8 +108,12 @@
             }
             endMapping(node.getNameExpressionNode());
         }
-
-        startMapping(node);
+        if (node.getMetaTags() != null) {
+            //offset mapping by any metadata tags that will be in the first child node
+            startMapping(node.getChild(1));
+        } else {
+            startMapping(node);
+        }
         write(ASEmitterTokens.SPACE);
         writeToken(ASEmitterTokens.EQUAL);
         write(ASEmitterTokens.FUNCTION);
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/PackageFooterEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/PackageFooterEmitter.java
index 0048b91..86bc80d 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/PackageFooterEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/PackageFooterEmitter.java
@@ -37,12 +37,14 @@
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.utils.EmitterUtils;
+import org.apache.royale.compiler.internal.definitions.ClassDefinition;
 import org.apache.royale.compiler.internal.driver.js.goog.JSGoogConfiguration;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
 import org.apache.royale.compiler.internal.tree.as.SetterNode;
 import org.apache.royale.compiler.problems.UnknownTypeProblem;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.scopes.IASScope;
+import org.apache.royale.compiler.scopes.IDefinitionSet;
 import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.*;
 import org.apache.royale.compiler.tree.metadata.IMetaTagNode;
@@ -74,13 +76,13 @@
         JSRoyaleDocEmitter doc = (JSRoyaleDocEmitter) getEmitter()
         .getDocEmitter();
 
-		boolean isInterface = tnode instanceof IInterfaceNode;
-
-	    if (!getEmitter().getModel().isExterns)
+	    if (!getEmitter().getModel().isExterns && doc.getEmitExports())
 	    {
-		    /*
+			boolean isInterface = tnode instanceof IInterfaceNode;
+			boolean isDynamic = tnode instanceof IClassNode && tnode.hasModifier(ASModifier.DYNAMIC);
+			/*
 		     * Metadata
-		     * 
+		     *
 		     * @type {Object.<string, Array.<Object>>}
 		     */
 		    writeNewline();
@@ -123,7 +125,19 @@
 			write(ASEmitterTokens.SINGLE_QUOTE);
 			if (isInterface) write(JSRoyaleEmitterTokens.ROYALE_CLASS_INFO_INTERFACE_KIND);
 			else write(JSRoyaleEmitterTokens.ROYALE_CLASS_INFO_CLASS_KIND);
-			writeToken(ASEmitterTokens.SINGLE_QUOTE);
+			//writeToken(ASEmitterTokens.SINGLE_QUOTE);
+			
+			if (isDynamic) {
+				//only add the 'isDynamic' tag when it is needed
+				write(ASEmitterTokens.SINGLE_QUOTE);
+				writeToken(ASEmitterTokens.COMMA);
+				write(JSRoyaleEmitterTokens.ROYALE_CLASS_INFO_IS_DYNAMIC);
+				writeToken(ASEmitterTokens.COLON);
+				write(ASEmitterTokens.TRUE);
+			} else {
+				writeToken(ASEmitterTokens.SINGLE_QUOTE);
+			}
+			
 		    write(ASEmitterTokens.BLOCK_CLOSE);
 		    write(ASEmitterTokens.SQUARE_CLOSE);
 	
@@ -184,14 +198,18 @@
 	
 			String typeName = getEmitter().formatQualifiedName(tnode.getQualifiedName());
 	
-		    emitReflectionData(
-		    		typeName,
+			emitReflectionData(
+					typeName,
 					reflectionKind,
-		    		varData,
-		    		accessorData,
-		    		methodData,
-		    		metadata);
-		    
+					varData,
+					accessorData,
+					methodData,
+					metadata);
+			
+		    if (!isInterface) {
+		    	emitReflectionRegisterInitialStaticFields(typeName, (ClassDefinition) tnode.getDefinition());
+			}
+		   
 		    emitExportProperties(typeName, exportProperties, exportSymbols);
 	    }
     }
@@ -249,7 +267,7 @@
     	methodData = new ArrayList<MethodData>();
     	/*
 	     * Reflection
-	     * 
+	     *
 	     * @return {Object.<string, Function>}
 	     */
         IDefinitionNode[] dnodes;
@@ -278,14 +296,14 @@
 					//todo consider outputting consts, none output for now
 					continue;
 				}
-                if (ns == IASKeywordConstants.PUBLIC || isInterface)
+                if (isInterface || (ns != null && ns.equals(IASKeywordConstants.PUBLIC )))
                 {
                 	name = varNode.getName();
 
 					IMetaTagsNode metaData = varNode.getMetaTags();
 					//first deal with 'Bindable' upgrades to getters/setters
 					if (!isInterface && bindableVars.containsKey(name)
-							&& bindableVars.get(name).namespace == IASKeywordConstants.PUBLIC) {
+							&& bindableVars.get(name).namespace.equals(IASKeywordConstants.PUBLIC)) {
 
 						AccessorData bindableAccessor = new AccessorData();
 						bindableAccessor.name = name;
@@ -347,7 +365,7 @@
 			staticEventDispatcher.isStatic = true;
 			accessorData.add(staticEventDispatcher);
 		}
-        
+     
 	    HashMap<String, AccessorData> instanceAccessorMap = new HashMap<String, AccessorData>();
 		HashMap<String, AccessorData> staticAccessorMap = new HashMap<String, AccessorData>();
         for (IDefinitionNode dnode : dnodes)
@@ -362,7 +380,8 @@
             {
             	IFunctionNode fnNode = (IFunctionNode)dnode;
                 String ns = fnNode.getNamespace();
-                if (ns == IASKeywordConstants.PUBLIC || isInterface)
+
+                if (isInterface || (ns != null && ns.equals(IASKeywordConstants.PUBLIC)))
                 {
 					String accessorName = fnNode.getName();
                 	AccessorData data = accessorMap.get(accessorName);
@@ -426,7 +445,7 @@
             {
             	IFunctionNode fnNode = (IFunctionNode)dnode;
                 String ns = fnNode.getNamespace();
-                if (ns == IASKeywordConstants.PUBLIC || isInterface)
+                if (isInterface || (ns != null && ns.equals(IASKeywordConstants.PUBLIC)))
                 {
                 	MethodData data = new MethodData();
 					data.isStatic = isStatic;
@@ -519,6 +538,8 @@
 	}
 
 	private void emitReflectionDataEnd(String typeName) {
+		JSGoogConfiguration config = ((RoyaleJSProject)getWalker().getProject()).config;
+		
 		writeNewline();
 		// close return object
 		write(ASEmitterTokens.BLOCK_CLOSE);
@@ -529,6 +550,28 @@
 		writeNewline();
 		write(ASEmitterTokens.BLOCK_CLOSE);
 		writeNewline(ASEmitterTokens.SEMICOLON);
+		
+		if (config == null) return;
+		//add compiletime descriptor flags
+		//doc emitter-ish:
+		writeNewline("/**");
+		writeNewline(" * @export");
+		writeNewline(" * @const");
+		writeNewline(" * @type {number}");
+		writeNewline(" */");
+		
+		//{typeName}.prototype.ROYALE_REFLECTION_INFO.compileFlags = {int value here};
+		write(typeName);
+		write(ASEmitterTokens.MEMBER_ACCESS);
+		write(JSEmitterTokens.PROTOTYPE);
+		write(ASEmitterTokens.MEMBER_ACCESS);
+		write(JSRoyaleEmitterTokens.ROYALE_REFLECTION_INFO);
+		write(ASEmitterTokens.MEMBER_ACCESS);
+		writeToken(JSRoyaleEmitterTokens.ROYALE_REFLECTION_INFO_COMPILE_TIME_FLAGS);
+		writeToken(ASEmitterTokens.EQUAL);
+		//
+		write(String.valueOf(config.getReflectionFlags()));
+		writeNewline(ASEmitterTokens.SEMICOLON);
 	}
     
     public void emitReflectionData(
@@ -538,7 +581,6 @@
     		List<AccessorData> accessorData,
     		List<MethodData> methodData,
     		IMetaTagNode[] metaData
-
     		)
     {
 
@@ -586,13 +628,48 @@
 					write(ASEmitterTokens.SINGLE_QUOTE);
 					write(var.type);
 					write(ASEmitterTokens.SINGLE_QUOTE);
-				//	if (var.isStatic) {
-				//		writeIsStatic();
-				//	}
+					
+					//provide a get_set function that works in release build with public vars
+					writeToken(ASEmitterTokens.COMMA);
+					write(JSRoyaleEmitterTokens.ROYALE_REFLECTION_INFO_GET_SET);
+					writeToken(ASEmitterTokens.COLON);
+					writeToken(ASEmitterTokens.FUNCTION);
+					boolean valueIsUntyped = var.type.equals("*");
+					if (valueIsUntyped) {
+						//give the function a local name because a self-reference argument will be used to signify that
+						//it is not being used as a setter (because 'undefined' is a valid possible value to set)
+						write("f");
+					}
+					write(ASEmitterTokens.PAREN_OPEN);
+					
+					if (!var.isStatic) {
+						//instance type parameter
+						writeToken("/** " + typeName + " */");
+						write("inst");
+						writeToken(ASEmitterTokens.COMMA);
+					}
+					//any type for value
+					write("/** * */ v");
+					writeToken(ASEmitterTokens.PAREN_CLOSE);
+					write(ASEmitterTokens.BLOCK_OPEN);
+					String getterSetter;
+					String field = var.isStatic ? typeName + "." + var.name : "inst." + var.name;
+					if (valueIsUntyped) {
+						//to avoid setting when type is '*' set the 'value' param to the function being called, which
+						//causes a 'getter only' result
+						//In the case of no parameter or literal undefined being passed, it will be treated as the value
+						//of undefined to be assigned to the variable field
+						getterSetter = "return v !== f ? "+ field + " = v : " + field + ";";
+					} else {
+						getterSetter = "return v !== undefined ? " + field + " = v : " + field + ";";
+					}
+					write(getterSetter);
+					write(ASEmitterTokens.BLOCK_CLOSE);
+					
 					IMetaTagNode[] tags = var.metaData;
 					if (tags != null) {
-						writeToken(ASEmitterTokens.COMMA);
-						writeMetaData(tags);
+						//writeToken(ASEmitterTokens.COMMA);
+						writeMetaData(tags, true, false);
 					}
 					// close object
 					write(ASEmitterTokens.BLOCK_CLOSE);
@@ -651,9 +728,6 @@
 				write(ASEmitterTokens.SINGLE_QUOTE);
 				write(accessor.type);
 				write(ASEmitterTokens.SINGLE_QUOTE);
-			//	if (accessor.isStatic) {
-			//		writeIsStatic();
-			//	}
 				writeToken(ASEmitterTokens.COMMA);
 				write("access");
 				writeToken(ASEmitterTokens.COLON);
@@ -669,8 +743,8 @@
 				IMetaTagNode[] tags = accessor.metaData;
 				if (tags != null)
 				{
-					writeToken(ASEmitterTokens.COMMA);
-					writeMetaData(tags);
+					//writeToken(ASEmitterTokens.COMMA);
+					writeMetaData(tags, true, false);
 				}
 				// close object
 				write(ASEmitterTokens.BLOCK_CLOSE);
@@ -728,9 +802,6 @@
 				write(ASEmitterTokens.SINGLE_QUOTE);
 				write(method.type);
 				write(ASEmitterTokens.SINGLE_QUOTE);
-			//	if (method.isStatic) {
-			//		writeIsStatic();
-			//	}
 				writeToken(ASEmitterTokens.COMMA);
 				write("declaredBy");
 				writeToken(ASEmitterTokens.COLON);
@@ -747,8 +818,8 @@
 				IMetaTagNode[] metas = method.metaData;
 				if (metas != null)
 				{
-					writeToken(ASEmitterTokens.COMMA);
-					writeMetaData(metas);
+					//writeToken(ASEmitterTokens.COMMA);
+					writeMetaData(metas, true, false);
 				}
 
 				// close object
@@ -764,18 +835,15 @@
 			// close method function
 			write(ASEmitterTokens.BLOCK_CLOSE);
 		}
-
-
-
+		
     	if (metaData != null && metaData.length > 0)
     	{
-    		write(ASEmitterTokens.COMMA);
-    	    writeNewline();
-    	    writeMetaData(metaData);
-    	}            	    	
+    		//write(ASEmitterTokens.COMMA);
+    	    //writeNewline();
+    	    writeMetaData(metaData, true, true);
+    	}
 	    
 	    indentPop();
-
 		emitReflectionDataEnd(typeName);
     }
 
@@ -798,13 +866,7 @@
 		writeToken(ASEmitterTokens.SQUARE_CLOSE);
 	}
 	*/
-    
-	/*private void writeIsStatic() {
-		writeToken(ASEmitterTokens.COMMA);
-		write("isStatic");
-		writeToken(ASEmitterTokens.COLON);
-		writeToken(ASEmitterTokens.TRUE);
-	}*/
+ 
 
 	private void writeEmptyContent(Boolean appendComma, Boolean includeNewline) {
 		//return {};
@@ -830,7 +892,6 @@
 		// return [ array of parameter definitions ]
 		writeToken(ASEmitterTokens.RETURN);
 		writeToken(ASEmitterTokens.SQUARE_OPEN);
-		write(ASEmitterTokens.SPACE);
 
 		int len = params.length;
 		for (int i = 0; i < len ; i++) {
@@ -872,96 +933,116 @@
 		// close function
 		write(ASEmitterTokens.BLOCK_CLOSE);
 	}
-    
-    private void writeMetaData(IMetaTagNode[] tags)
-    {
-    	JSGoogConfiguration config = ((RoyaleJSProject)getWalker().getProject()).config;
-    	Set<String> allowedNames = config.getCompilerKeepAs3Metadata();
-    	
-	    // metadata: function() {
-		write("metadata");
-	    writeToken(ASEmitterTokens.COLON);
-	    writeToken(ASEmitterTokens.FUNCTION);
-	    write(ASEmitterTokens.PAREN_OPEN);
-	    writeToken(ASEmitterTokens.PAREN_CLOSE);
-	    writeToken(ASEmitterTokens.BLOCK_OPEN);
-	    // return [ array of metadata tags ]
-	    writeToken(ASEmitterTokens.RETURN);
-	    writeToken(ASEmitterTokens.SQUARE_OPEN);
-
+	
+	private ArrayList<IMetaTagNode> getAllowedMetadata(IMetaTagNode[] tags) {
+		JSGoogConfiguration config = ((RoyaleJSProject)getWalker().getProject()).config;
+		Set<String> allowedNames = config.getCompilerKeepAs3Metadata();
+		
 		ArrayList<IMetaTagNode> filteredTags = new ArrayList<IMetaTagNode>(tags.length);
 		for (IMetaTagNode tag : tags)
 		{
 			if (allowedNames.contains(tag.getTagName())) filteredTags.add(tag);
-
 		}
-
-	    int count = 0;
+		return filteredTags;
+	}
+	
+	private void writeAllowedMetadata(ArrayList<IMetaTagNode> filteredTags ) {
+		int count = 0;
 		int len = filteredTags.size();
-	    for (IMetaTagNode tag : filteredTags)
-	    {
-
-
-	    	count++;
-    	    // { name: <tag name>
-    	    writeToken(ASEmitterTokens.BLOCK_OPEN);
-    	    write("name");
-    	    writeToken(ASEmitterTokens.COLON);
-    	    write(ASEmitterTokens.SINGLE_QUOTE);
-    	    write(tag.getTagName());
-    	    write(ASEmitterTokens.SINGLE_QUOTE);
-    	    IMetaTagAttribute[] args = tag.getAllAttributes();
-    	    if (args.length > 0)
-    	    {
-        		writeToken(ASEmitterTokens.COMMA);
-        	    
-        	    // args: [
-        	    write("args");
-        	    writeToken(ASEmitterTokens.COLON);
-        	    writeToken(ASEmitterTokens.SQUARE_OPEN);
-        	    
-        	    for (int j = 0; j < args.length; j++)
-        	    {
-        	    	if (j > 0)
-        	    	{
-                		writeToken(ASEmitterTokens.COMMA);
-        	    	}
-        	    	// { key: key, value: value }
-        	    	IMetaTagAttribute arg = args[j];
-            	    writeToken(ASEmitterTokens.BLOCK_OPEN);
-            	    write("key");
-            	    writeToken(ASEmitterTokens.COLON);
-            	    write(ASEmitterTokens.SINGLE_QUOTE);
-            	    String key = arg.getKey();
-            	    write(key == null ? "" : key);
-            	    write(ASEmitterTokens.SINGLE_QUOTE);
-            		writeToken(ASEmitterTokens.COMMA);
-            	    write("value");
-            	    writeToken(ASEmitterTokens.COLON);
-            	    write(ASEmitterTokens.SINGLE_QUOTE);
-            	    write(formatJSStringValue(arg.getValue()));
-            	    write(ASEmitterTokens.SINGLE_QUOTE);
+		
+		// metadata: function() {
+		write("metadata");
+		writeToken(ASEmitterTokens.COLON);
+		writeToken(ASEmitterTokens.FUNCTION);
+		write(ASEmitterTokens.PAREN_OPEN);
+		writeToken(ASEmitterTokens.PAREN_CLOSE);
+		writeToken(ASEmitterTokens.BLOCK_OPEN);
+		// return [ array of metadata tags ]
+		writeToken(ASEmitterTokens.RETURN);
+		writeToken(ASEmitterTokens.SQUARE_OPEN);
+		
+		for (IMetaTagNode tag : filteredTags)
+		{
+			count++;
+			// { name: <tag name>
+			writeToken(ASEmitterTokens.BLOCK_OPEN);
+			write("name");
+			writeToken(ASEmitterTokens.COLON);
+			write(ASEmitterTokens.SINGLE_QUOTE);
+			write(tag.getTagName());
+			write(ASEmitterTokens.SINGLE_QUOTE);
+			IMetaTagAttribute[] args = tag.getAllAttributes();
+			if (args.length > 0)
+			{
+				writeToken(ASEmitterTokens.COMMA);
+				
+				// args: [
+				write("args");
+				writeToken(ASEmitterTokens.COLON);
+				writeToken(ASEmitterTokens.SQUARE_OPEN);
+				
+				for (int j = 0; j < args.length; j++)
+				{
+					if (j > 0)
+					{
+						writeToken(ASEmitterTokens.COMMA);
+					}
+					// { key: key, value: value }
+					IMetaTagAttribute arg = args[j];
+					writeToken(ASEmitterTokens.BLOCK_OPEN);
+					write("key");
+					writeToken(ASEmitterTokens.COLON);
+					write(ASEmitterTokens.SINGLE_QUOTE);
+					String key = arg.getKey();
+					write(key == null ? "" : key);
+					write(ASEmitterTokens.SINGLE_QUOTE);
+					writeToken(ASEmitterTokens.COMMA);
+					write("value");
+					writeToken(ASEmitterTokens.COLON);
+					write(ASEmitterTokens.SINGLE_QUOTE);
+					write(formatJSStringValue(arg.getValue()));
+					write(ASEmitterTokens.SINGLE_QUOTE);
 					write(ASEmitterTokens.SPACE);
-            	    write(ASEmitterTokens.BLOCK_CLOSE);
-        	    }
-        	    // close array of args
+					write(ASEmitterTokens.BLOCK_CLOSE);
+				}
+				// close array of args
 				write(ASEmitterTokens.SPACE);
-        	    write(ASEmitterTokens.SQUARE_CLOSE);
-    	    }
-    	    // close metadata object
+				write(ASEmitterTokens.SQUARE_CLOSE);
+			}
+			// close metadata object
 			write(ASEmitterTokens.SPACE);
-    	    write(ASEmitterTokens.BLOCK_CLOSE);
+			write(ASEmitterTokens.BLOCK_CLOSE);
 			if (count > 0 && count < len)
 			{
 				writeToken(ASEmitterTokens.COMMA);
 			}
-	    }
-	    // close array of metadatas
+		}
+		// close array of metadatas
 		write(ASEmitterTokens.SPACE);
-	    write(ASEmitterTokens.SQUARE_CLOSE);
-	    writeToken(ASEmitterTokens.SEMICOLON);
-	    // close function
-	    write(ASEmitterTokens.BLOCK_CLOSE);
+		write(ASEmitterTokens.SQUARE_CLOSE);
+		writeToken(ASEmitterTokens.SEMICOLON);
+		// close function
+		write(ASEmitterTokens.BLOCK_CLOSE);
+	}
+    
+    private void writeMetaData(IMetaTagNode[] tags, boolean prefixComma, boolean prefixNewline)
+    {
+		ArrayList<IMetaTagNode> filteredTags = getAllowedMetadata(tags);
+		if (filteredTags.size() == 0) {
+			//nothing to write
+			return;
+		}
+		if (prefixNewline) {
+			if (prefixComma) {
+				write(ASEmitterTokens.COMMA);
+			}
+			writeNewline();
+		} else {
+			if (prefixComma) {
+				writeToken(ASEmitterTokens.COMMA);
+			}
+		}
+		writeAllowedMetadata(filteredTags);
     }
 
     private String formatJSStringValue(String value) {
@@ -969,6 +1050,52 @@
     	value = value.replace("'","\\'");
     	return value;
 	}
+	
+	public void emitReflectionRegisterInitialStaticFields(String typeName, IClassDefinition classDef) {
+		//this is only output if the default initializers are enabled (otherwise runtime reflection results are not reliable)
+		//local config check here (instead of call site check) - in case this needs to change in the future:
+		JSGoogConfiguration config = ((RoyaleJSProject)getWalker().getProject()).config;
+		if (config == null || !config.getJsDefaultInitializers()) return;
+		
+		boolean needsStaticsList = false;
+		Collection<IDefinitionSet> defs = classDef.getContainedScope().getAllLocalDefinitionSets();
+		for (IDefinitionSet set : defs) {
+			for (int i = 0, l = set.getSize(); i < l; ++i) {
+				IDefinition d = set.getDefinition(i);
+				if (d.isStatic()) {
+					needsStaticsList = true;
+					break;
+				}
+			}
+			if (needsStaticsList) break;
+		}
+		if (needsStaticsList) {
+			//support for reflection on static classes: supports ability to distinguish between initial fields and dynamic fields
+			//doc emitter-ish:
+			writeNewline("/**");
+			writeNewline(" * Provide reflection support for distinguishing dynamic fields on class object (static)");
+			writeNewline(" * @export");
+			writeNewline(" * @const");
+			writeNewline(" * @type {Array<string>}");
+			writeNewline(" */");
+			
+			//{typeName}.prototype.ROYALE_REFLECTION_INFO.statics = Object.keys({typeName});
+			write(typeName);
+			write(ASEmitterTokens.MEMBER_ACCESS);
+			write(JSEmitterTokens.PROTOTYPE);
+			write(ASEmitterTokens.MEMBER_ACCESS);
+			write(JSRoyaleEmitterTokens.ROYALE_REFLECTION_INFO);
+			write(ASEmitterTokens.MEMBER_ACCESS);
+			writeToken(JSRoyaleEmitterTokens.ROYALE_REFLECTION_INFO_INITIAL_STATICS);
+			writeToken(ASEmitterTokens.EQUAL);
+			write("Object.keys");
+			write(ASEmitterTokens.PAREN_OPEN);
+			write(typeName);
+			write(ASEmitterTokens.PAREN_CLOSE);
+			write(ASEmitterTokens.SEMICOLON);
+			writeNewline();
+		}
+	}
     
     public void emitExportProperties(String typeName, ArrayList<String> exportProperties, ArrayList<String> exportSymbols)
     {
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/PackageHeaderEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/PackageHeaderEmitter.java
index 2d7f52d..d5ef151 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/PackageHeaderEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/PackageHeaderEmitter.java
@@ -142,7 +142,7 @@
         }
 
         writeNewline("/**");
-        writeNewline(" * Generated by Apache Royale Compiler from " + sourceName);
+        writeNewline(" * Generated by Apache Royale Compiler from " + sourceName.replace('\\', '/'));
         writeNewline(" * " + qname);
         writeNewline(" *");
         writeNewline(" * @fileoverview");
@@ -380,9 +380,6 @@
 
                 if (imp.equals(cname))
                     continue;
-
-                if (project.sourceExterns.contains(imp))
-                	continue;
                 
                 if (NativeUtils.isNative(imp))
                 {
@@ -395,9 +392,13 @@
                     continue;
                 }
 
+                if(!project.isGoogProvided(imp))
+                {
+                    continue;
+                }
+
                 if (writtenRequires.indexOf(imp) == -1)
                 {
-
                     /* goog.require('x');\n */
                     write(JSGoogEmitterTokens.GOOG_REQUIRE);
                     write(ASEmitterTokens.PAREN_OPEN);
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ReturnEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ReturnEmitter.java
index a7f5d7e..0573110 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ReturnEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ReturnEmitter.java
@@ -21,10 +21,12 @@
 
 import org.apache.royale.compiler.codegen.ISubEmitter;
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
+import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSSubEmitter;
 import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IExpressionNode;
+import org.apache.royale.compiler.tree.as.IFunctionNode;
 import org.apache.royale.compiler.tree.as.IReturnNode;
 
 public class ReturnEmitter extends JSSubEmitter implements
@@ -51,7 +53,17 @@
 
         if (hasReturnValue)
         {
-            getWalker().walk(rnode);
+            IDefinition returnDef = null;
+            IFunctionNode parentFn = (IFunctionNode) node.getAncestorOfType(IFunctionNode.class);
+            if (parentFn != null)
+            {
+                IExpressionNode returnTypeNode = parentFn.getReturnTypeNode();
+                if (returnTypeNode != null)
+                {
+                    returnDef = returnTypeNode.resolve(getProject());
+                }
+            }
+            getEmitter().emitAssignmentCoercion(rnode, returnDef);
         }
     }
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/SourceMapDirectiveEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/SourceMapDirectiveEmitter.java
index 4109f1e..3dece8e 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/SourceMapDirectiveEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/SourceMapDirectiveEmitter.java
@@ -40,6 +40,8 @@
         super(emitter);
     }
 
+    public boolean isExterns = false;
+
     @Override
     public void emit(ITypeNode node)
     {
@@ -56,7 +58,7 @@
             }
         }
 
-        if (sourceMap)
+        if (sourceMap && !isExterns)
         {
             String name = node.getName() + EXTENSION_JS;
             if (node instanceof IMXMLDocumentNode)
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/SuperCallEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/SuperCallEmitter.java
index 02f6972..285773b 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/SuperCallEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/SuperCallEmitter.java
@@ -73,14 +73,24 @@
             IClassNode cnode = (IClassNode) node
                     .getAncestorOfType(IClassNode.class);
 
-            IExpressionNode fcNameNode = fcnode.getNameNode();
-            // assume it is memberaccess of the form super.somefunction
-            MemberAccessExpressionNode mae = null;
-            if (fcNameNode.getNodeID() == ASTNodeID.MemberAccessExpressionID)
-            	mae = (MemberAccessExpressionNode)fcNameNode;
-            if (mae != null
-                    && (mae.getRightOperandNode().getNodeID() == ASTNodeID.GetterID || mae.getRightOperandNode()
-                            .getNodeID() == ASTNodeID.SetterID))
+            boolean isGetterSetter = false;
+            if (fcnode != null)
+            {
+	            IExpressionNode fcNameNode = fcnode.getNameNode();
+	            // assume it is memberaccess of the form super.somefunction
+	            MemberAccessExpressionNode mae = null;
+	            if (fcNameNode.getNodeID() == ASTNodeID.MemberAccessExpressionID)
+	            	mae = (MemberAccessExpressionNode)fcNameNode;
+	            if (mae != null
+	                    && (mae.getRightOperandNode().getNodeID() == ASTNodeID.GetterID || mae.getRightOperandNode()
+	                            .getNodeID() == ASTNodeID.SetterID))
+	            	isGetterSetter = true;
+            }
+            else if (fnode != null && (fnode.getNodeID() == ASTNodeID.GetterID || fnode.getNodeID() == ASTNodeID.SetterID))
+            {
+            	isGetterSetter = true;            	
+            }
+            if (isGetterSetter)
             {
                 if (cnode == null && thisClass != null)
                     write(getEmitter().formatQualifiedName(
@@ -204,7 +214,6 @@
         }
 
         boolean usingApply = false;
-        boolean isCustomNamespace = false;
         if (fnode != null && !fnode.isConstructor())
         {
             write(ASEmitterTokens.MEMBER_ACCESS);
@@ -226,21 +235,12 @@
             	if (nsDef.getContainingScope() != null) // was null for flash_proxy in unit test
             		fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
     			String s = nsDef.getURI();
-    			superName = s + "::" + superName;
-    			isCustomNamespace = true;
-            }
-            if (isCustomNamespace)
-            {
-            	write(ASEmitterTokens.SQUARE_OPEN);
-            	write(ASEmitterTokens.SINGLE_QUOTE);
+    			write(JSRoyaleEmitter.formatNamespacedProperty(s, superName, true));
             }
             else
-                write(ASEmitterTokens.MEMBER_ACCESS);
-            write(superName);
-            if (isCustomNamespace)
             {
-            	write(ASEmitterTokens.SINGLE_QUOTE);
-                write(ASEmitterTokens.SQUARE_CLOSE);
+                write(ASEmitterTokens.MEMBER_ACCESS);
+                write(superName);
             }
             write(ASEmitterTokens.MEMBER_ACCESS);
             write(JSEmitterTokens.APPLY);
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/UnaryOperatorEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/UnaryOperatorEmitter.java
index b575d55..bc040e7 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/UnaryOperatorEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/UnaryOperatorEmitter.java
@@ -23,8 +23,12 @@
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens;
+import org.apache.royale.compiler.internal.definitions.AppliedVectorDefinition;
+import org.apache.royale.compiler.internal.tree.as.*;
 import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IExpressionNode;
+import org.apache.royale.compiler.tree.as.ILiteralNode;
 import org.apache.royale.compiler.tree.as.IUnaryOperatorNode;
 import org.apache.royale.compiler.utils.ASNodeUtils;
 
@@ -41,6 +45,31 @@
     {
         if (ASNodeUtils.hasParenOpen(node))
             write(ASEmitterTokens.PAREN_OPEN);
+        
+        Boolean isAssignment = (node.getNodeID() == ASTNodeID.Op_PreIncrID
+                || node.getNodeID() == ASTNodeID.Op_PreDecrID
+                || node.getNodeID() == ASTNodeID.Op_PostIncrID
+                || node.getNodeID() == ASTNodeID.Op_PostDecrID);
+        
+        if (isAssignment && (node.getOperandNode() instanceof MemberAccessExpressionNode)
+                && (((MemberAccessExpressionNode)(node.getOperandNode())).getRightOperandNode() instanceof IdentifierNode)
+                && ((IdentifierNode)(((MemberAccessExpressionNode)(node.getOperandNode())).getRightOperandNode())).getName().equals("length")
+                && ((MemberAccessExpressionNode)(node.getOperandNode())).getLeftOperandNode().resolveType(getProject()) instanceof AppliedVectorDefinition
+        ) {
+            //support for output of alternate length setter, example: vectorInst.length++ as vectorInst['_synthType'].length++
+            //likewise for pre/post increment/decrement
+            
+            String synthTagName = JSRoyaleEmitterTokens.LANGUAGE_QNAME.getToken() + ASEmitterTokens.MEMBER_ACCESS.getToken() + JSRoyaleEmitterTokens.ROYALE_SYNTH_TAG_FIELD_NAME.getToken();
+            LiteralNode synthType = new LiteralNode(ILiteralNode.LiteralType.STRING, synthTagName);
+            synthType.setSynthetic(true);
+            DynamicAccessNode patchedVectorReference = new DynamicAccessNode(((ExpressionNodeBase)((MemberAccessExpressionNode) node.getOperandNode()).getLeftOperandNode()));
+            ((ExpressionNodeBase)((MemberAccessExpressionNode) node.getOperandNode()).getLeftOperandNode()).setParent(patchedVectorReference);
+            patchedVectorReference.setRightOperandNode(synthType);
+            synthType.setParent(patchedVectorReference);
+            patchedVectorReference.setParent((NodeBase) node.getOperandNode());
+            patchedVectorReference.setSourceLocation(((MemberAccessExpressionNode) node.getOperandNode()).getLeftOperandNode());
+            ((MemberAccessExpressionNode) node.getOperandNode()).setLeftOperandNode(patchedVectorReference);
+        }
 
         if (node.getNodeID() == ASTNodeID.Op_PreIncrID
                 || node.getNodeID() == ASTNodeID.Op_PreDecrID
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
index bead66f..70be284 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
@@ -22,26 +22,25 @@
 import org.apache.royale.compiler.codegen.ISubEmitter;
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
 import org.apache.royale.compiler.constants.IASKeywordConstants;
-import org.apache.royale.compiler.constants.IASLanguageConstants;
 import org.apache.royale.compiler.definitions.IDefinition;
-import org.apache.royale.compiler.definitions.metadata.IMetaTag;
-import org.apache.royale.compiler.definitions.metadata.IMetaTagAttribute;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSSubEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter;
+import org.apache.royale.compiler.internal.codegen.js.utils.EmitterUtils;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
 import org.apache.royale.compiler.internal.tree.as.ChainedVariableNode;
-import org.apache.royale.compiler.internal.tree.as.DynamicAccessNode;
-import org.apache.royale.compiler.internal.tree.as.FunctionCallNode;
-import org.apache.royale.compiler.internal.tree.as.IdentifierNode;
-import org.apache.royale.compiler.internal.tree.as.MemberAccessExpressionNode;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IASNode;
 import org.apache.royale.compiler.tree.as.IEmbedNode;
 import org.apache.royale.compiler.tree.as.IExpressionNode;
+import org.apache.royale.compiler.tree.as.IFunctionNode;
 import org.apache.royale.compiler.tree.as.IVariableNode;
 
+/**
+ * Local variable in a function. For member and static variables of a class, see
+ * FieldEmitter instead.
+ */
 public class VarDeclarationEmitter extends JSSubEmitter implements
         ISubEmitter<IVariableNode>
 {
@@ -59,15 +58,37 @@
 
         getModel().getVars().add(node);
         
+        boolean defaultInitializers = false;
+        ICompilerProject project = getProject();
+        if(project instanceof RoyaleJSProject)
+        {
+            RoyaleJSProject fjsProject = (RoyaleJSProject) project; 
+            if(fjsProject.config != null)
+            {
+                defaultInitializers = fjsProject.config.getJsDefaultInitializers();
+            }
+        }
+        boolean needsDefaultValue = EmitterUtils.needsDefaultValue(node, defaultInitializers, getProject());
+
+        IFunctionNode parentFnNode = (IFunctionNode) node.getAncestorOfType(IFunctionNode.class);
+        boolean isHoisting = fjs.isEmittingHoistedNodes(parentFnNode);
+        
+        if (!(node instanceof ChainedVariableNode) && !isHoisting && needsDefaultValue)
+        {
+            write("//");
+        }
+
         if (!(node instanceof ChainedVariableNode) && !node.isConst())
         {
             fjs.emitMemberKeyword(node);
         }
 
         IExpressionNode variableTypeNode = node.getVariableTypeNode();
+        IDefinition variableDef = null;
         boolean hasVariableType = variableTypeNode.getLine() >= 0;
         if(hasVariableType)
         {
+            variableDef = variableTypeNode.resolve(getProject());
             startMapping(variableTypeNode,
                     variableTypeNode.getLine(),
                     variableTypeNode.getColumn() - 1); //include the :
@@ -83,19 +104,19 @@
                     nameExpressionNode.getColumn() + nameExpressionNode.getAbsoluteEnd() - nameExpressionNode.getAbsoluteStart());
         }
         IExpressionNode avnode = node.getAssignedValueNode();
-        IDefinition avdef = null;
+        IDefinition avtypedef = null;
         if (avnode != null)
         {
-        	avdef = avnode.resolveType(getWalker().getProject());
+        	avtypedef = avnode.resolveType(getProject());
             String opcode = avnode.getNodeID().getParaphrase();
             if (opcode != "AnonymousFunction")
             {
-                fjs.getDocEmitter().emitVarDoc(node, avdef, getWalker().getProject());
+                fjs.getDocEmitter().emitVarDoc(node, avtypedef, getProject());
             }
         }
         else
         {
-            fjs.getDocEmitter().emitVarDoc(node, null, getWalker().getProject());
+            fjs.getDocEmitter().emitVarDoc(node, null, getProject());
         }
         endMapping(variableTypeNode);
 
@@ -105,7 +126,12 @@
         }
 
         fjs.emitDeclarationName(node);
-        if (avnode != null && !(avnode instanceof IEmbedNode))
+
+        if (avnode == null)
+        {
+            emitDefaultInitializer(node, defaultInitializers);
+        }
+        else if(!(avnode instanceof IEmbedNode))
         {
             if (hasVariableType)
             {
@@ -118,141 +144,119 @@
             write(ASEmitterTokens.SPACE);
             writeToken(ASEmitterTokens.EQUAL);
             endMapping(node);
-            boolean varIsNumber = (variableTypeNode.getNodeID() == ASTNodeID.IdentifierID && 
-            		  (((IdentifierNode)variableTypeNode).getName().equals(IASLanguageConstants.Number) ||
-            		   ((IdentifierNode)variableTypeNode).getName().equals(IASLanguageConstants._int) ||
-            		   ((IdentifierNode)variableTypeNode).getName().equals(IASLanguageConstants.uint)));
-            boolean valIsNumber = (avdef != null && (avdef.getQualifiedName().equals(IASLanguageConstants.Number) ||
-            										 avdef.getQualifiedName().equals(IASLanguageConstants._int) ||
-            										 avdef.getQualifiedName().equals(IASLanguageConstants.uint)));
-            if (!valIsNumber && avdef == null && avnode.getNodeID() == ASTNodeID.MemberAccessExpressionID &&
-            		fjs.isDateProperty(avnode, false))
-            	valIsNumber = true;
-            if (varIsNumber && !valIsNumber && (avdef == null || avdef.getQualifiedName().equals(IASLanguageConstants.ANY_TYPE)))
-            {
-        		if (avnode.getNodeID() == ASTNodeID.FunctionCallID)
-        		{
-	            	IExpressionNode fnNameNode = ((FunctionCallNode)avnode).getNameNode();
-	            	if (fnNameNode.getNodeID() == ASTNodeID.MemberAccessExpressionID)
-	            	{
-	            		MemberAccessExpressionNode mae = (MemberAccessExpressionNode)fnNameNode;
-	            		IExpressionNode rightNode = mae.getRightOperandNode();
-	            		valIsNumber = rightNode.getNodeID() == ASTNodeID.IdentifierID && 
-	            				((IdentifierNode)rightNode).getName().equals("length") &&
-	            				fjs.isXMLList(mae);
-	            	}
-        		}
-        		else if (avnode.getNodeID() == ASTNodeID.ArrayIndexExpressionID)
-        		{
-        			DynamicAccessNode dyn = (DynamicAccessNode)avnode;
-        			IDefinition leftDef = dyn.getLeftOperandNode().resolveType(getProject());
-        			IDefinition rightDef = dyn.getRightOperandNode().resolveType(getProject());
-        			// numeric indexing?
-        			if (rightDef.getQualifiedName().equals(IASLanguageConstants.Number))
-        			{
-        				IMetaTag[] metas = leftDef.getAllMetaTags();
-        				for (IMetaTag meta : metas)
-        				{
-        					if (meta.getTagName().equals("ArrayElementType"))
-        					{
-        						IMetaTagAttribute[] attrs = meta.getAllAttributes();
-        						for (IMetaTagAttribute attr : attrs)
-        						{
-        							String t = attr.getValue();
-            						if (t.equals(IASLanguageConstants.Number))
-            							valIsNumber = true;
-        						}
-        					}
-        				}
-        			}
-        		}
-            }
-            String coercion = "";
-            if (varIsNumber && !valIsNumber)
-            	coercion = "Number(";
-            if (variableTypeNode.getNodeID() == ASTNodeID.IdentifierID &&
-                	((IdentifierNode)variableTypeNode).getName().equals(IASLanguageConstants.String) &&
-                	(avdef == null || (!avdef.getQualifiedName().equals(IASLanguageConstants.String) &&
-                			            !avdef.getQualifiedName().equals(IASLanguageConstants.Null))))
-                	coercion = "org.apache.royale.utils.Language.string(";
-            write(coercion);
-            fjs.emitAssignedValue(avnode);
-            if (coercion.length() > 0)
-              	write(")");
+            getEmitter().emitAssignmentCoercion(avnode, variableDef);
         }
-        if (avnode == null)
+
+        emitChainedVariables(node, defaultInitializers, isHoisting);
+    }
+
+    private void emitDefaultInitializer(IVariableNode node, boolean defaultInitializers)
+    {
+        IDefinition typedef = null;
+        IExpressionNode enode = node.getVariableTypeNode();
+        if (enode != null)
         {
-            IDefinition typedef = null;
-            IExpressionNode enode = node.getVariableTypeNode();//getAssignedValueNode();
-            if (enode != null)
-                typedef = enode.resolveType(getWalker().getProject());
-            if (typedef != null)
+            typedef = enode.resolveType(getProject());
+        }
+        if (typedef != null)
+        {
+            if (node.getParent() != null &&
+                    node.getParent().getParent() != null &&
+                    node.getParent().getParent().getNodeID() != ASTNodeID.Op_InID)
             {
-                boolean defaultInitializers = false;
-                ICompilerProject project = getProject();
-                if(project instanceof RoyaleJSProject)
+                String defName = typedef.getQualifiedName();
+                if (defName.equals("int") || defName.equals("uint"))
                 {
-                    RoyaleJSProject fjsProject = (RoyaleJSProject) project; 
-                    if(fjsProject.config != null)
-                    {
-                        defaultInitializers = fjsProject.config.getJsDefaultInitializers();
-                    }
+                    write(ASEmitterTokens.SPACE);
+                    writeToken(ASEmitterTokens.EQUAL);
+                    write("0");
                 }
-                if (node.getParent() != null &&
-                        node.getParent().getParent() != null &&
-                        node.getParent().getParent().getNodeID() != ASTNodeID.Op_InID)
+                else if (defaultInitializers)
                 {
-                    String defName = typedef.getQualifiedName();
-                    if (defName.equals("int") || defName.equals("uint"))
+                    if (defName.equals("Number"))
                     {
                         write(ASEmitterTokens.SPACE);
                         writeToken(ASEmitterTokens.EQUAL);
-                        write("0");
+                        write(IASKeywordConstants.NA_N);
                     }
-                    else if (defaultInitializers)
+                    else if (defName.equals("Boolean"))
                     {
-                        if (defName.equals("Number"))
-                        {
-                            write(ASEmitterTokens.SPACE);
-                            writeToken(ASEmitterTokens.EQUAL);
-                            write(IASKeywordConstants.NA_N);
-                        }
-                        else if (defName.equals("Boolean"))
-                        {
-                            write(ASEmitterTokens.SPACE);
-                            writeToken(ASEmitterTokens.EQUAL);
-                            write(IASKeywordConstants.FALSE);
-                        }
-                        else if (!defName.equals("*"))
-                        {
-                            //type * is meant to default to undefined, so it
-                            //doesn't need to be initialized, but everything
-                            //else should default to null
-                            write(ASEmitterTokens.SPACE);
-                            writeToken(ASEmitterTokens.EQUAL);
-                            write(IASKeywordConstants.NULL);
-                        }
+                        write(ASEmitterTokens.SPACE);
+                        writeToken(ASEmitterTokens.EQUAL);
+                        write(IASKeywordConstants.FALSE);
                     }
-                }
-            }
-        }
-
-        if (!(node instanceof ChainedVariableNode))
-        {
-            // check for chained variables
-            int len = node.getChildCount();
-            for (int i = 0; i < len; i++)
-            {
-                IASNode child = node.getChild(i);
-                if (child instanceof ChainedVariableNode)
-                {
-                    startMapping(node, node.getChild(i - 1));
-                    writeToken(ASEmitterTokens.COMMA);
-                    endMapping(node);
-                    fjs.emitVarDeclaration((IVariableNode) child);
+                    else if (!defName.equals("*"))
+                    {
+                        //type * is meant to default to undefined, so it
+                        //doesn't need to be initialized, but everything
+                        //else should default to null
+                        write(ASEmitterTokens.SPACE);
+                        writeToken(ASEmitterTokens.EQUAL);
+                        write(IASKeywordConstants.NULL);
+                    }
                 }
             }
         }
     }
 
+    private void emitChainedVariables(IVariableNode node, boolean defaultInitializers, boolean isHoisting)
+    {
+        JSRoyaleEmitter fjs = (JSRoyaleEmitter) getEmitter();
+        if (!(node instanceof ChainedVariableNode))
+        {
+            // check for chained variables
+            int len = node.getChildCount();
+            boolean splitVariables = false;
+            for (int i = 0; i < len; i++)
+            {
+                IASNode child = node.getChild(i);
+                if (child instanceof ChainedVariableNode)
+                {
+                    ChainedVariableNode varChild = (ChainedVariableNode) child;
+                    //if any of them need a default value, they all should be
+                    //split onto different lines
+                    if(EmitterUtils.needsDefaultValue(varChild, defaultInitializers, getProject()))
+                    {
+                        splitVariables = true;
+                        break;
+                    }
+                }
+            }
+
+            for (int i = 0; i < len; i++)
+            {
+                IASNode child = node.getChild(i);
+                if (child instanceof ChainedVariableNode)
+                {
+                    if (splitVariables)
+                    {
+                        boolean childNeedsDefault = EmitterUtils.needsDefaultValue((IVariableNode) child, defaultInitializers, getProject());
+                        if (isHoisting && !childNeedsDefault)
+                        {
+                            //this one does not need to be hoisted because it
+                            //already has a default value
+                            continue;
+                        }
+                        startMapping(node, node.getChild(i - 1));
+                        write(ASEmitterTokens.SEMICOLON);
+                        endMapping(node);
+                        writeNewline();
+                        if (!isHoisting && childNeedsDefault)
+                        {
+                            write("//");
+                        }
+                        writeToken(ASEmitterTokens.VAR);
+                    }
+                    else
+                    {
+                        startMapping(node, node.getChild(i - 1));
+                        writeToken(ASEmitterTokens.COMMA);
+                        endMapping(node);
+                    }
+                    fjs.emitVarDeclaration((IVariableNode) child);
+                }
+            }
+            
+        }
+    }
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleASDocDITAEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleASDocDITAEmitter.java
index 266a0d6..c9a0863 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleASDocDITAEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleASDocDITAEmitter.java
@@ -20,6 +20,7 @@
 package org.apache.royale.compiler.internal.codegen.js.royale;
 
 import java.io.File;
+import java.io.BufferedWriter;
 import java.io.FileWriter;
 import java.io.FilterWriter;
 import java.io.IOException;
@@ -1015,10 +1016,13 @@
     
     public void outputIndex(File outputFolder, RoyaleASDocProject project) throws IOException
     {
-	    final File indexFile = new File(outputFolder, "index.json");
-	    FileWriter out = new FileWriter(indexFile);
+		final File indexFile = new File(outputFolder, "index.json");
+		BufferedWriter out = new BufferedWriter(new FileWriter(indexFile));
 		out.write("{  \"index\": [");
-	    System.out.println("Compiling file: " + indexFile);
+		if (project.config.isVerbose())
+		{
+			System.out.println("Compiling file: " + indexFile);
+		}
     	Set<String> keys = project.index.keySet();
     	List<String> keyList = new ArrayList<String>(keys);
     	Collections.sort(keyList);
@@ -1084,10 +1088,13 @@
 
     public void outputClasses(File outputFolder, RoyaleASDocProject project) throws IOException
     {
-	    final File indexFile = new File(outputFolder, "classes.json");
-	    FileWriter out = new FileWriter(indexFile);
+		final File indexFile = new File(outputFolder, "classes.json");
+		BufferedWriter out = new BufferedWriter(new FileWriter(indexFile));
 		out.write("{  \"classes\": [");
-	    System.out.println("Compiling file: " + indexFile);
+		if (project.config.isVerbose())
+		{
+			System.out.println("Compiling file: " + indexFile);
+		}
     	Set<String> keys = project.classes.keySet();
     	List<String> keyList = new ArrayList<String>(keys);
     	Collections.sort(keyList);
@@ -1122,10 +1129,13 @@
     
     public void outputTags(File outputFolder, RoyaleASDocProject project) throws IOException
     {
-	    final File indexFile = new File(outputFolder, "tags.json");
-	    FileWriter out = new FileWriter(indexFile);
+		final File indexFile = new File(outputFolder, "tags.json");
+		BufferedWriter out = new BufferedWriter(new FileWriter(indexFile));
 		out.write("{  \"tags\": [");
-	    System.out.println("Compiling file: " + indexFile);
+		if (project.config.isVerbose())
+		{
+			System.out.println("Compiling file: " + indexFile);
+		}
     	Collections.sort(project.tags);
     	boolean firstLine = true;
     	for (String tag : project.tags)
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleASDocEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleASDocEmitter.java
index d8a3d84..07c840a 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleASDocEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleASDocEmitter.java
@@ -19,6 +19,7 @@
 
 package org.apache.royale.compiler.internal.codegen.js.royale;
 
+import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileWriter;
 import java.io.FilterWriter;
@@ -194,7 +195,7 @@
 	        }
 	        else if (pnode instanceof IClassNode)
 	        {
-	        	getWalker().walk(pnode);
+	        	//getWalker().walk(pnode); don't emit internal classes outside of a package
 	        }
 	        else if (pnode instanceof IInterfaceNode)
 	        {
@@ -232,6 +233,9 @@
     @Override
     public void emitClass(IClassNode node)
     {
+    	if (!node.getDefinition().isPublic())
+    		return;
+    	
         ASDocComment asDoc = (ASDocComment) node.getASDocComment();
         writeNewline("{ \"type\": \"class\",");
         write("  \"qname\": \"");
@@ -619,7 +623,11 @@
     	List<String> tagList = project.tags;
     	asDoc.compile();
         write("  \"description\": \"");
-    	write(asDoc.getDescription());
+        String d = asDoc.getDescription();
+		d = d.replace("\t", " ");
+		d = d.replace("\"", "&quot;");
+		d = d.replace("\\", "\\\\");
+    	write(d);
 		write("\"");
     	Map<String, List<IASDocTag>> tags = asDoc.getTags();
     	if (tags != null)
@@ -653,7 +661,11 @@
     					if (!firstOne) write(", ");
     					firstOne = false;
     					write("\"");
-    					write(value.getDescription().trim());
+    					d = value.getDescription().trim();
+    					d = d.replace("\t", " ");
+    					d = d.replace("\"", "&quot;");
+    					d = d.replace("\\", "\\\\");
+    					write(d);
     					write("\"");
     				}
     			}
@@ -724,19 +736,37 @@
     	writeNewline(",");
         if (def.isDeprecated())
         {
-        	writeNewline(",");
         	IDeprecationInfo dep = def.getDeprecationInfo();
             writeNewline("  \"deprecated\": {");
             indentPush();
-            write("  \"message\":  \"");
-            write(dep.getMessage());
-            writeNewline("\",");
-            write("  \"replacement\":  \"");
-            write(dep.getReplacement());
-            writeNewline("\",");
-            write("  \"since\":  \"");
-            write(dep.getSince());
-            writeNewline("\"}");
+            String comma = "";
+            String msg = dep.getMessage();
+            if (msg != null)
+            {
+	            write("  \"message\":  \"");
+	            write(msg);
+	            write("\"");
+	            comma = ",";
+            }
+            String replace = dep.getReplacement();
+            if (replace != null)
+            {
+            	writeNewline(comma);
+            	write("  \"replacement\":  \"");
+            	write(replace);
+	            write("\"");
+	            comma = ",";
+            }
+            String since = dep.getSince();
+            if (since != null)
+            {
+	            writeNewline("\",");
+	            write("  \"since\":  \"");
+	            write(since);
+	            write("\"");
+	            comma = ",";
+            }
+            writeNewline("}");
         }
         else
         {
@@ -813,10 +843,13 @@
 
     public void outputIndex(File outputFolder, RoyaleASDocProject project) throws IOException
     {
-	    final File indexFile = new File(outputFolder, "index" + getMiddle(project) + ".json");
-	    FileWriter out = new FileWriter(indexFile);
+		final File indexFile = new File(outputFolder, "index" + getMiddle(project) + ".json");
+		BufferedWriter out = new BufferedWriter(new FileWriter(indexFile));
 		out.write("{  \"index\": [");
-	    System.out.println("Compiling file: " + indexFile);
+		if (project.config.isVerbose())
+		{
+			System.out.println("Compiling file: " + indexFile);
+		}
     	Set<String> keys = project.index.keySet();
     	List<String> keyList = new ArrayList<String>(keys);
     	Collections.sort(keyList);
@@ -896,11 +929,10 @@
     	return false;
     }
     
-    private void writeCommentaryValues(FileWriter commentaryWriter, List<IASDocTag> values) throws IOException
+    private void writeCommentaryValues(BufferedWriter commentaryWriter, List<IASDocTag> values) throws IOException
     {
     	HashMap<String, String> map = new HashMap<String, String>();
 		boolean firstOne = true;
-		int count = 0;
 		for (IASDocTag value : values) {
 		    String description = value.getDescription().trim();
 			if (map.containsKey(description)) {
@@ -914,11 +946,10 @@
 			commentaryWriter.write("\"");
 			
 			map.put(description, "true");
-			count++;
 		}
     }
     
-    public void writeCommentaryFile(FileWriter commentaryWriter, String qname, ASDocComment asDoc) throws IOException
+    public void writeCommentaryFile(BufferedWriter commentaryWriter, String qname, ASDocComment asDoc) throws IOException
     {
     	//asDoc.compile();
     	Map<String, List<IASDocTag>> tags = asDoc.getTags();
@@ -1006,10 +1037,13 @@
 
     public void outputClasses(File outputFolder, RoyaleASDocProject project) throws IOException
     {
-	    final File indexFile = new File(outputFolder, "classes" + getMiddle(project) + ".json");
-	    FileWriter out = new FileWriter(indexFile);
-		out.write("{  \"classes\": [");
-	    System.out.println("Compiling file: " + indexFile);
+		final File indexFile = new File(outputFolder, "classes" + getMiddle(project) + ".json");
+		BufferedWriter out = new BufferedWriter(new FileWriter(indexFile));
+        out.write("{  \"classes\": [");
+		if (project.config.isVerbose())
+		{
+			System.out.println("Compiling file: " + indexFile);
+		}
     	Set<String> keys = project.classes.keySet();
     	List<String> keyList = new ArrayList<String>(keys);
     	Collections.sort(keyList);
@@ -1067,9 +1101,12 @@
 		}
 		
 	    final File listFile = new File(outputFolder, "classlist" + getMiddle(project) + ".json");
-	    out = new FileWriter(listFile);
+	    out = new BufferedWriter(new FileWriter(listFile));
 		out.write("{  \"classnames\": [");
-	    System.out.println("Compiling file: " + listFile);
+	    if (project.config.isVerbose())
+		{
+			System.out.println("Compiling file: " + listFile);
+		}
     	firstLine = true;
     	
     	for (String key : keyList)
@@ -1077,7 +1114,6 @@
     		if (!firstLine)
     			out.write(",\n");
     		firstLine = false;
-        	RoyaleASDocProject.ASDocRecord record = project.classes.get(key);
         	out.write("\"");
         	out.write(key);
         	out.write("\"");
@@ -1099,9 +1135,12 @@
 		
 		if (commentaryList.size() > 0) {    	
 			final File commentaryFile = new File(outputFolder, "commentary" + getMiddle(project) + ".json");
-			FileWriter commentaryWriter = new FileWriter(commentaryFile);
+			BufferedWriter commentaryWriter = new BufferedWriter(new FileWriter(commentaryFile));
 			commentaryWriter.write("{ \"list\": [");
-			System.out.println("Building commentary comparison file: "+commentaryFile);
+			if (project.config.isVerbose())
+			{
+				System.out.println("Building commentary comparison file: "+commentaryFile);
+			}
 			
 			firstLine = true;
 			int index = 0;
@@ -1132,10 +1171,13 @@
     
     public void outputTags(File outputFolder, RoyaleASDocProject project) throws IOException
     {
-	    final File indexFile = new File(outputFolder, "tags" + getMiddle(project) + ".json");
-	    FileWriter out = new FileWriter(indexFile);
+		final File indexFile = new File(outputFolder, "tags" + getMiddle(project) + ".json");
+		BufferedWriter out = new BufferedWriter(new FileWriter(indexFile));
 		out.write("{  \"tags\": [");
-	    System.out.println("Compiling file: " + indexFile);
+		if (project.config.isVerbose())
+		{
+			System.out.println("Compiling file: " + indexFile);
+		}
     	Collections.sort(project.tags);
     	boolean firstLine = true;
     	for (String tag : project.tags)
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleDocEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleDocEmitter.java
index 71ecd89..0c32ad3 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleDocEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleDocEmitter.java
@@ -19,10 +19,10 @@
 
 package org.apache.royale.compiler.internal.codegen.js.royale;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
 
 import org.apache.royale.compiler.asdoc.royale.ASDocComment;
+import org.apache.royale.compiler.codegen.as.IASEmitter;
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
 import org.apache.royale.compiler.common.ASModifier;
 import org.apache.royale.compiler.common.DependencyType;
@@ -37,20 +37,14 @@
 import org.apache.royale.compiler.internal.codegen.js.JSEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSSessionModel;
 import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogDocEmitter;
-import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogDocEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.jx.BindableEmitter;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
 import org.apache.royale.compiler.internal.scopes.ASScope;
+import org.apache.royale.compiler.parsing.IASToken;
 import org.apache.royale.compiler.problems.PublicVarWarningProblem;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.ASTNodeID;
-import org.apache.royale.compiler.tree.as.IASNode;
-import org.apache.royale.compiler.tree.as.IClassNode;
-import org.apache.royale.compiler.tree.as.IDefinitionNode;
-import org.apache.royale.compiler.tree.as.IExpressionNode;
-import org.apache.royale.compiler.tree.as.IFunctionNode;
-import org.apache.royale.compiler.tree.as.IParameterNode;
-import org.apache.royale.compiler.tree.as.IVariableNode;
+import org.apache.royale.compiler.tree.as.*;
 import org.apache.royale.compiler.tree.metadata.IMetaTagNode;
 import org.apache.royale.compiler.tree.metadata.IMetaTagsNode;
 
@@ -59,8 +53,12 @@
     private List<String> classIgnoreList;
     private List<String> ignoreList;
     private List<String> coercionList;
+    private Map<String,List<String>> localSettings;
     public boolean emitStringConversions = true;
     private boolean emitExports = true;
+    private boolean exportProtected = false;
+    
+    private boolean suppressClosure = false;
 
     public JSRoyaleDocEmitter(IJSEmitter emitter)
     {
@@ -76,6 +74,14 @@
     {
         this.classIgnoreList = value;
     }
+    
+    public Boolean getSuppressClosure() {
+        return suppressClosure;
+    }
+    
+    public Boolean getEmitExports() {
+        return emitExports;
+    }
 
     @Override
     protected String convertASTypeToJS(String name, String pname)
@@ -96,9 +102,19 @@
                 return IASLanguageConstants.Object;
         }
         if (name.matches("Vector\\.<.*>"))
-        	return IASLanguageConstants.Array;
+        {
+        	RoyaleJSProject fjp = (RoyaleJSProject)((IASEmitter)emitter).getWalker().getProject();
+        	String vectorClassName = fjp.config == null ? null : fjp.config.getJsVectorEmulationClass();
+        	if (vectorClassName != null) return vectorClassName;
+        	return super.convertASTypeToJS(name, pname);
+        }
         
         name = super.convertASTypeToJS(name, pname);
+        if (name.equals(IASLanguageConstants.Boolean.toLowerCase())
+                || name.equals(IASLanguageConstants.String.toLowerCase())
+                || name.equals(IASLanguageConstants.Number.toLowerCase()))
+            return name;
+
         return formatQualifiedName(name);
     }
 
@@ -115,12 +131,21 @@
     {
     	RoyaleJSProject fjp = (RoyaleJSProject)project;
         boolean keepASDoc = fjp.config != null && fjp.config.getKeepASDoc();
+        boolean suppressExports = false;
+        if (emitter instanceof JSRoyaleEmitter) {
+            suppressExports = ((JSRoyaleEmitter) emitter).getModel().suppressExports;
+        }
         if (fjp.config != null)
-        	emitExports = fjp.config.getExportPublicSymbols();
+        {
+        	emitExports = !suppressExports && fjp.config.getExportPublicSymbols();
+        	exportProtected = !suppressExports && fjp.config.getExportProtectedSymbols();
+        }
         
         coercionList = null;
         ignoreList = null;
+        localSettings = null;
         emitStringConversions = true;
+        suppressClosure = false;
 
         IClassDefinition classDefinition = resolveClassDefinition(node);
 
@@ -220,6 +245,31 @@
                         		.getToken();
 		                if (docText.contains(noStringToken))
 		                    emitStringConversions = false;
+    
+                        String noImplicitComplexCoercion = JSRoyaleEmitterTokens.SUPPRESS_COMPLEX_IMPLICIT_COERCION
+                                .getToken();
+                        if (docText.contains(noImplicitComplexCoercion))
+                            loadLocalSettings(docText, noImplicitComplexCoercion, "true");
+		                
+                        String noResolveUncertain = JSRoyaleEmitterTokens.SUPPRESS_RESOLVE_UNCERTAIN
+                                .getToken();
+                        if (docText.contains(noResolveUncertain))
+                            loadLocalSettings(docText,noResolveUncertain, "true");
+		                
+                        String suppressVectorIndexCheck = JSRoyaleEmitterTokens.SUPPRESS_VECTOR_INDEX_CHECK
+                                .getToken();
+                        if (docText.contains(suppressVectorIndexCheck))
+                            loadLocalSettings(docText,suppressVectorIndexCheck, "true");
+                        
+                        String suppressClosureToken = JSRoyaleEmitterTokens.SUPPRESS_CLOSURE.getToken();
+    
+                        if (docText.contains(suppressClosureToken))
+                            suppressClosure = true;
+                        
+                        String suppressExport = JSRoyaleEmitterTokens.SUPPRESS_EXPORT.getToken();
+                        if (docText.contains(suppressExport))
+                            emitExports = false;
+                        
                         write(changeAnnotations(asDoc.commentNoEnd()));
                     }
                     else
@@ -304,6 +354,78 @@
                 end();
         }
     }
+    
+    private void loadLocalSettings(String doc, String settingToken, String defaultSetting)
+    {
+        if (localSettings == null) localSettings = new HashMap<String, List<String>>();
+        int index = doc.indexOf(settingToken);
+        List<String> settings = localSettings.containsKey(settingToken) ? localSettings.get(settingToken) : null;
+        while (index != -1)
+        {
+            String setting = doc.substring(index + settingToken.length());
+            int endIndex = setting.indexOf("\n");
+            setting = setting.substring(0, endIndex);
+            setting = setting.trim();
+            if (settings == null) {
+                settings = new ArrayList<String>();
+                localSettings.put(settingToken, settings);
+            }
+            List<String> settingItems = null;
+            if (setting.length() >0) {
+                settingItems = Arrays.asList(setting.split("\\s*(,\\s*)+"));
+            } else {
+                settingItems =  Arrays.asList(defaultSetting);
+            }
+            for (String settingItem: settingItems) {
+                if (settings.contains(settingItem)) {
+                    //change the order to reflect the latest addition
+                    settings.remove(settingItem);
+                }
+                settings.add(settingItem);
+                //System.out.println("---Adding setting "+settingToken+":"+settingItem);
+            }
+            index = doc.indexOf(settingToken, index +  settingToken.length());
+        }
+    }
+    
+    public boolean hasLocalSetting(String settingToken) {
+        if (localSettings == null) return false;
+        return (localSettings.keySet().contains(settingToken));
+    }
+    
+    public boolean getLocalSettingAsBoolean(JSRoyaleEmitterTokens token, Boolean defaultValue) {
+        return getLocalSettingAsBoolean(token.getToken(), defaultValue);
+    }
+    
+    public boolean getLocalSettingAsBoolean(String settingToken, Boolean defaultValue) {
+        boolean setting = defaultValue;
+        if (hasLocalSetting(settingToken)) {
+            for (String stringVal: localSettings.get(settingToken)) {
+                //don't bail out after finding a boolean-ish string val
+                //'last one wins'
+                if (stringVal.equals("false")) setting = false;
+                else if (stringVal.equals("true")) setting = true;
+            }
+        }
+        return setting;
+    }
+    
+    public boolean getLocalSettingIncludesString(JSRoyaleEmitterTokens token, String searchValue) {
+        return getLocalSettingIncludesString(token.getToken(), searchValue);
+    }
+    
+    public boolean getLocalSettingIncludesString(String settingToken, String searchValue) {
+        boolean hasValue = false;
+        if (hasLocalSetting(settingToken)) {
+            for (String stringVal: localSettings.get(settingToken)) {
+                if (stringVal.equals(searchValue)) {
+                    hasValue = true;
+                    break;
+                }
+            }
+        }
+        return hasValue;
+    }
 
     private void loadIgnores(String doc)
     {
@@ -405,7 +527,7 @@
         {
             emitProtected(node);
         }
-        else if (ns != null && ns == IASKeywordConstants.PUBLIC)
+        else /*if (ns != null && ns == IASKeywordConstants.PUBLIC)*/
         {
             emitPublic(node);
         }
@@ -437,12 +559,35 @@
             	if (tag != null)
             		bindable = true;
             }
-            if (warnPublicVars && !node.isConst() && !bindable)
+            if (warnPublicVars && !node.isConst() && !bindable && ns.contentEquals("public"))
             {
+                IASNode warningNode = node;
+                //find "public" child node, which may not be the start of the IVariableNode node because of associated metadata
+                int childCount = node.getChildCount();
+                int index = 0;
+                while (index < childCount) {
+                    IASNode child = node.getChild(index);
+                    if (child instanceof IIdentifierNode && ((IIdentifierNode) child).getName().equals("public")) {
+                        warningNode = child;
+                        break;
+                    }
+                    index++;
+                }
+                
                 if (!suppressedWarning(node, fjp))
-                	fjp.getProblems().add(new PublicVarWarningProblem(node));
+                	fjp.getProblems().add(new PublicVarWarningProblem(node.getSourcePath(),
+                            node.getStart(), node.getEnd(),
+                            warningNode.getLine(), warningNode.getColumn(),
+                            node.getEndLine(), node.getEndColumn()));
+               
+
             }
-            emitPublic(node);
+            if (!(node.getASDocComment() instanceof ASDocComment
+                    && ((ASDocComment)node.getASDocComment()).commentNoEnd()
+                    .contains(JSRoyaleEmitterTokens.SUPPRESS_EXPORT.getToken()))) {
+                emitPublic(node);
+            }
+            
         }
 
         if (node.isConst())
@@ -452,12 +597,21 @@
         if (def != null)
             packageName = def.getPackageName();
 
-        emitType(node, project.getActualPackageName(packageName));
+        emitType(node, project.getActualPackageName(packageName), project);
 
         end();
     }
 
     @Override
+    public void emitProtected(IASNode node)
+    {
+    	if (exportProtected)
+    		super.emitPublic(node);
+    	else
+    		super.emitProtected(node);
+    }
+    
+    @Override
     public void emitPublic(IASNode node)
     {
     	if (emitExports)
@@ -466,7 +620,6 @@
     
     private boolean suppressedWarning(IVariableNode node, RoyaleJSProject fjp)
     {
-    	boolean suppressed = false;
         ASDocComment asDoc = (ASDocComment) node.getASDocComment();
         boolean keepASDoc = fjp.config != null && fjp.config.getKeepASDoc();
         String suppressToken = JSRoyaleEmitterTokens.SUPPRESS_PUBLIC_VAR_WARNING
@@ -492,6 +645,8 @@
             IClassDefinition cdef = ((IClassNode)classNode).getDefinition();
             if (cdef.isBindable())
             	return true;
+            if (!cdef.isPublic())
+            	return true;
     	}
     	return false;
     }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java
index f258b16..d3a65ab 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java
@@ -23,7 +23,10 @@
 import java.io.FilterWriter;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.royale.compiler.codegen.js.royale.IJSRoyaleEmitter;
@@ -36,6 +39,7 @@
 import org.apache.royale.compiler.definitions.INamespaceDefinition;
 import org.apache.royale.compiler.definitions.IPackageDefinition;
 import org.apache.royale.compiler.definitions.ITypeDefinition;
+import org.apache.royale.compiler.definitions.IVariableDefinition;
 import org.apache.royale.compiler.definitions.metadata.IMetaTagAttribute;
 import org.apache.royale.compiler.definitions.references.INamespaceResolvedReference;
 import org.apache.royale.compiler.embedding.EmbedAttribute;
@@ -75,8 +79,10 @@
 import org.apache.royale.compiler.internal.projects.CompilerProject;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
 import org.apache.royale.compiler.internal.projects.RoyaleProject;
+import org.apache.royale.compiler.internal.semantics.SemanticUtils;
 import org.apache.royale.compiler.internal.tree.as.*;
 import org.apache.royale.compiler.problems.EmbedUnableToReadSourceProblem;
+import org.apache.royale.compiler.problems.FilePrivateItemsWithMainVarWarningProblem;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IASNode;
@@ -152,6 +158,8 @@
     public ArrayList<String> usedNames = new ArrayList<String>();
     public ArrayList<String> staticUsedNames = new ArrayList<String>();
     private boolean needNamespace;
+    
+    private Set<IFunctionNode> emittingHoistedNodes = new HashSet<IFunctionNode>();
 
     @Override
     public String postProcess(String output)
@@ -173,14 +181,17 @@
             String line = lines[i];
     		if (stillSearching)
     		{
-                int c = line.indexOf(JSGoogEmitterTokens.GOOG_PROVIDE.getToken());
-                if (c != -1)
+                if (provideIndex == -1 || !sawRequires)
                 {
-                    // if zero requires are found, require Language after the
-                    // call to goog.provide
-                    provideIndex = addIndex = i + 1;
+                    int c = line.indexOf(JSGoogEmitterTokens.GOOG_PROVIDE.getToken());
+                    if (c != -1)
+                    {
+                        // if zero requires are found, require Language after the
+                        // call to goog.provide
+                        provideIndex = addIndex = i + 1;
+                    }
                 }
-	            c = line.indexOf(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
+	            int c = line.indexOf(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
 	            if (c != -1)
 	            {
                     // we found other requires, so we'll just add Language at
@@ -401,17 +412,35 @@
     @Override
     public void emitLocalNamedFunction(IFunctionNode node)
     {
-		IFunctionNode fnNode = (IFunctionNode)node.getAncestorOfType(IFunctionNode.class);
-    	if (fnNode.getEmittingLocalFunctions())
+        IFunctionNode parentFnNode = (IFunctionNode) node.getAncestorOfType(IFunctionNode.class);
+        if (parentFnNode == null || isEmittingHoistedNodes(parentFnNode))
     	{
+            // emit named functions only when allowed
     		super.emitLocalNamedFunction(node);
-    	}
+        }
+    }
+
+    public Boolean isEmittingHoistedNodes(IFunctionNode node)
+    {
+        return emittingHoistedNodes.contains(node);
+    }
+
+    protected void setEmittingHoistedNodes(IFunctionNode node, boolean emit)
+    {
+        if (emit)
+        {
+            emittingHoistedNodes.add(node);
+        }
+        else
+        {
+            emittingHoistedNodes.remove(node);
+        }
     }
 
     @Override
     public void emitFunctionBlockHeader(IFunctionNode node)
     {
-    	node.setEmittingLocalFunctions(true);
+        setEmittingHoistedNodes(node, true);
     	super.emitFunctionBlockHeader(node);
     	if (node.isConstructor())
     	{
@@ -424,47 +453,133 @@
                     bindableEmitter.emitBindableExtendsConstructorCode(cnode.getDefinition().getQualifiedName(),false);
             }
             emitComplexInitializers(cnode);
-
     	}
-        if (node.containsLocalFunctions())
+
+        emitHoistedFunctionsCodeBlock(node);
+
+        if (!getModel().isExterns)
+            emitHoistedVariablesCodeBlock(node);
+
+        setEmittingHoistedNodes(node, false);
+    }
+
+    protected void emitHoistedFunctionsCodeBlock(IFunctionNode node)
+    {
+        if (!node.containsLocalFunctions())
         {
-            List<IFunctionNode> anonFns = node.getLocalFunctions();
-            int n = anonFns.size();
-            for (int i = 0; i < n; i++)
+            return;
+        }
+        List<IFunctionNode> localFns = node.getLocalFunctions();
+        int n = localFns.size();
+        for (int i = 0; i < n; i++)
+        {
+            IFunctionNode localFn = localFns.get(i);
+            // named functions need to be declared at the top level to
+            // comply with JS strict mode.
+            // anonymous functions can be emitted inline, so we'll do that.
+            if (localFn.getName().length() > 0)
             {
-                IFunctionNode anonFn = anonFns.get(i);
-                if (anonFn.getParent().getNodeID() == ASTNodeID.AnonymousFunctionID)
-                {
-                    write("var /** @type {Function} */ __localFn" + Integer.toString(i) + "__ = ");
-                	getWalker().walk(anonFn.getParent());
-                }
-                else
-                {
-                	getWalker().walk(anonFn);
-                	write(ASEmitterTokens.SEMICOLON);
-                }
+                getWalker().walk(localFn);
+                write(ASEmitterTokens.SEMICOLON);
                 this.writeNewline();
             }
         }
-    	node.setEmittingLocalFunctions(false);
+    }
+
+    protected void emitHoistedVariablesCodeBlock(IFunctionNode node)
+    {
+        boolean defaultInitializers = false;
+        ICompilerProject project = getWalker().getProject();
+        if(project instanceof RoyaleJSProject)
+        {
+            RoyaleJSProject fjsProject = (RoyaleJSProject) project; 
+            if(fjsProject.config != null)
+            {
+                defaultInitializers = fjsProject.config.getJsDefaultInitializers();
+            }
+        }
+        Collection<IDefinition> localDefs = node.getScopedNode().getScope().getAllLocalDefinitions();
+        for (IDefinition localDef : localDefs)
+        {
+            if (localDef instanceof IVariableDefinition)
+            {
+                IVariableDefinition varDef = (IVariableDefinition) localDef;
+                IVariableNode varNode = varDef.getVariableNode();
+                if (varNode == null)
+                {
+                    //no associated node is possible for implicit variables,
+                    //like "arguments"
+                    continue;
+                }
+                if (varNode instanceof ChainedVariableNode)
+                {
+                    //these will be handled from the first variable in the chain
+                    continue;
+                }
+                if (EmitterUtils.needsDefaultValue(varNode, defaultInitializers, getWalker().getProject()))
+                {
+                    emitVarDeclaration(varNode);
+                    write(ASEmitterTokens.SEMICOLON);
+                    writeNewline();
+                }
+                else
+                {
+                    //when the first varible in a chain doesn't need a default
+                    //value, we need to manually check the rest of the chain
+                    int len = varNode.getChildCount();
+                    for(int i = 0; i < len; i++)
+                    {
+                        IASNode child = varNode.getChild(i);
+                        if(child instanceof ChainedVariableNode)
+                        {
+                            ChainedVariableNode childVarNode = (ChainedVariableNode) child;
+                            if (EmitterUtils.needsDefaultValue(childVarNode, defaultInitializers, getWalker().getProject()))
+                            {
+                                writeToken(ASEmitterTokens.VAR);
+                                emitVarDeclaration(childVarNode);
+                                write(ASEmitterTokens.SEMICOLON);
+                                writeNewline();
+                            }
+                        }
+                    }
+                }
+            }
+        }
     }
 
     @Override
     public void emitFunctionObject(IFunctionObjectNode node)
     {
-		IFunctionNode fnNode = (IFunctionNode)node.getAncestorOfType(IFunctionNode.class);
-    	if (fnNode == null || fnNode.getEmittingLocalFunctions())
+		IFunctionNode parentFnNode = (IFunctionNode) node.getAncestorOfType(IFunctionNode.class);
+        IFunctionNode localFnNode = node.getFunctionNode();
+    	if (parentFnNode == null || isEmittingHoistedNodes(parentFnNode))
     	{
+            // emit named functions only when allowed
     		super.emitFunctionObject(node);
-    	}
+        }
+        else if(localFnNode.getName().length() == 0)
+        {
+            // anonymous functions are allowed to be inline
+    		super.emitFunctionObject(node);
+        }
     	else
     	{
-            List<IFunctionNode> anonFns = fnNode.getLocalFunctions();
-            int i = anonFns.indexOf(node.getFunctionNode());
+            List<IFunctionNode> localFns = parentFnNode.getLocalFunctions();
+            int i = localFns.indexOf(node.getFunctionNode());
             if (i < 0)
             	System.out.println("missing index for " + node.toString());
             else
-            	write("__localFn" + Integer.toString(i) + "__");
+            {
+            	IFunctionNode localFn = localFns.get(i);
+            	IExpressionNode idNode = localFn.getNameExpressionNode();
+            	String fnName = "";
+            	if (idNode != null && idNode.getNodeID() == ASTNodeID.IdentifierID)
+            		fnName = ((IdentifierNode)idNode).getName();
+            	if (!fnName.isEmpty())
+            		write(((IdentifierNode)idNode).getName());
+            	else
+            		write("__localFn" + Integer.toString(i) + "__");
+            }
     	}
     }
 
@@ -478,7 +593,8 @@
         writeToken(ASEmitterTokens.NEW);
         write(IASLanguageConstants.Namespace);
         write(ASEmitterTokens.PAREN_OPEN);
-        staticUsedNames.add(IASLanguageConstants.Namespace);
+        if (!staticUsedNames.contains(IASLanguageConstants.Namespace))
+        	staticUsedNames.add(IASLanguageConstants.Namespace);
         IExpressionNode uriNode = node.getNamespaceURINode();
         if (uriNode == null)
         {
@@ -514,7 +630,7 @@
     {
 		INamespaceDefinition nsDef = def.getNamespaceReference().resolveNamespaceReference(getWalker().getProject());
 		String uri = nsDef.getURI();
-		if (!def.getNamespaceReference().isLanguageNamespace() && !uri.equals(INamespaceConstants.AS3URI) && 
+		if (!def.getNamespaceReference().isLanguageNamespace() && !uri.equals(INamespaceConstants.AS3URI) &&
 						!nsDef.getBaseName().equals(ASEmitterTokens.PRIVATE.getToken()))
 			return true;
 		return false;
@@ -524,27 +640,40 @@
     public void emitMemberName(IDefinitionNode node)
     {
         ICompilerProject project = getWalker().getProject();
-    	if (node.getNodeID() == ASTNodeID.FunctionID)
-    	{
-    		FunctionNode fn = (FunctionNode)node;
-    		if (isCustomNamespace(fn))
-    		{
-    			INamespaceDecorationNode ns = ((FunctionNode)node).getActualNamespaceNode();
-    			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
-    			formatQualifiedName(nsDef.getQualifiedName()); // register with used names
-    			String s = nsDef.getURI();
-    			write("[\"" + s + "::" + node.getName() + "\"]");
-    			return;
-    		}
-    	}
-    	String qname = node.getName();
-    	IDefinition nodeDef = node.getDefinition();
-    	if (nodeDef != null && nodeDef.isPrivate() && project.getAllowPrivateNameConflicts())
-    		qname = formatPrivateName(nodeDef.getParent().getQualifiedName(), qname);
+        if (node.getNodeID() == ASTNodeID.FunctionID)
+        {
+            FunctionNode fn = (FunctionNode)node;
+            if (isCustomNamespace(fn))
+            {
+                INamespaceDecorationNode ns = ((FunctionNode)node).getActualNamespaceNode();
+                INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
+                formatQualifiedName(nsDef.getQualifiedName()); // register with used names
+                String s = nsDef.getURI();
+                write(formatNamespacedProperty(s, node.getName(), true));
+                return;
+            }
+        }
+        String qname = node.getName();
+        IDefinition nodeDef = node.getDefinition();
+        if (nodeDef != null && !nodeDef.isStatic() && nodeDef.isPrivate() && project.getAllowPrivateNameConflicts())
+            qname = formatPrivateName(nodeDef.getParent().getQualifiedName(), qname);
         write(qname);
     }
 
-    @Override
+    public static String formatNamespacedProperty(String s, String propName, boolean access) {
+    	//closure compiler choked on this syntax so stop using bracket notation for now
+    	//if (access) return "[\"" + s + "::" + propName + "\"]";
+    	//return "\"" + s + "::" + propName + "\"";
+    	s = s.replace(":", "_");
+    	s = s.replace(".", "_");
+    	s = s.replace("/", "$");
+    	s += "__" + propName;
+    	if (access)
+    		s = ASEmitterTokens.MEMBER_ACCESS.getToken() + s;
+    	return s;
+	}
+
+	@Override
     public String formatQualifiedName(String name)
     {
         return formatQualifiedName(name, false);
@@ -569,10 +698,13 @@
     	else if (!isDoc)
     	{
         	if (getModel().inStaticInitializer)
-        		if (!staticUsedNames.contains(name) && !NativeUtils.isJSNative(name) && !isExternal(name))
+        		if (!staticUsedNames.contains(name) && !NativeUtils.isJSNative(name)
+        				&& isGoogProvided(name) && !getModel().getCurrentClass().getQualifiedName().equals(name)
+        				&& (getModel().primaryDefinitionQName == null
+        					|| !getModel().primaryDefinitionQName.equals(name)))
         			staticUsedNames.add(name);
     		
-    		if (!usedNames.contains(name) && !isExternal(name))
+    		if (!usedNames.contains(name) && isGoogProvided(name))
     			usedNames.add(name);
     	}
         return name;
@@ -589,88 +721,99 @@
         else if (name.equals(IASLanguageConstants._int)
                 || name.equals(IASLanguageConstants.uint))
             result = IASLanguageConstants.Number;
-
-        boolean isBuiltinFunction = name.matches("Vector\\.<.*>");
-        if (isBuiltinFunction)
-        {
-        	result = IASLanguageConstants.Array;
+        else if (name.equals(IASLanguageConstants.Vector) || name.equals("__AS3__.vec.Vector")) {
+            result = JSRoyaleEmitterTokens.VECTOR.getToken();
         }
+        
         return result;
     }
 
     //--------------------------------------------------------------------------
     // Package Level
     //--------------------------------------------------------------------------
-
+    
     @Override
     public void emitPackageHeader(IPackageDefinition definition)
     {
-    	IPackageNode packageNode = definition.getNode();
-    	IFileNode fileNode = (IFileNode) packageNode.getAncestorOfType(IFileNode.class);
+        IPackageNode packageNode = definition.getNode();
+        IFileNode fileNode = (IFileNode) packageNode.getAncestorOfType(IFileNode.class);
         int nodeCount = fileNode.getChildCount();
         String mainClassName = null;
+        Boolean mainClassNameisVar = false;
+        IASNode firstInternalContent = null;
         for (int i = 0; i < nodeCount; i++)
         {
-	        IASNode pnode = fileNode.getChild(i);
-
-	        if (pnode instanceof IPackageNode)
-	        {
-	        	IScopedNode snode = ((IPackageNode)pnode).getScopedNode();
-	            int snodeCount = snode.getChildCount();
-	            for (int j = 0; j < snodeCount; j++)
-	            {
-	    	        IASNode cnode = snode.getChild(j);
-	    	        if (cnode instanceof IClassNode)
-	    	        {
-	    	        	mainClassName = ((IClassNode)cnode).getQualifiedName();
-	    	        	break;
-	    	        }
-	    	        else if (j == 0)
-	    	        {
-	    	            if (cnode instanceof IFunctionNode)
-	    	            {
-	    	                mainClassName = ((IFunctionNode)cnode).getQualifiedName();
-	    	            }
-	    	            else if (cnode instanceof INamespaceNode)
-	    	            {
-	    	            	mainClassName = ((INamespaceNode)cnode).getQualifiedName();
-	    	            }
-	    	            else if (cnode instanceof IVariableNode)
-	    	            {
-	    	            	mainClassName = ((IVariableNode)cnode).getQualifiedName();
-	    	            }
-	    	        	
-	    	        }
-	            }
-	        }
-	        else if (pnode instanceof IClassNode)
-	        {
-	        	String className = ((IClassNode)pnode).getQualifiedName();
-	        	getModel().getInternalClasses().put(className, mainClassName + "." + className);
-	        }
-	        else if (pnode instanceof IInterfaceNode)
-	        {
-	        	String className = ((IInterfaceNode)pnode).getQualifiedName();
-	        	getModel().getInternalClasses().put(className, mainClassName + "." + className);
-	        }
+            IASNode pnode = fileNode.getChild(i);
+            
+            if (pnode instanceof IPackageNode)
+            {
+                IScopedNode snode = ((IPackageNode)pnode).getScopedNode();
+                int snodeCount = snode.getChildCount();
+                for (int j = 0; j < snodeCount; j++)
+                {
+                    //there can only be one externally visible definition of either class, namespace, variable or function
+                    //and package scope does not permit other class level access modifiers, otherwise a compiler error has already occurred.
+                    //So mainClassName is derived from the first instance of any of these.
+                    IASNode cnode = snode.getChild(j);
+                    if (cnode instanceof IClassNode)
+                    {
+                        mainClassName = ((IClassNode)cnode).getQualifiedName();
+                        break;
+                    }
+                    else if (cnode instanceof IFunctionNode)
+                    {
+                        mainClassName = ((IFunctionNode)cnode).getQualifiedName();
+                        break;
+                    }
+                    else if (cnode instanceof INamespaceNode)
+                    {
+                        mainClassName = ((INamespaceNode)cnode).getQualifiedName();
+                        break;
+                    }
+                    else if (cnode instanceof IVariableNode)
+                    {
+                        mainClassName = ((IVariableNode)cnode).getQualifiedName();
+                        mainClassNameisVar = true;
+                        break;
+                    }
+                }
+            }
+            else if (pnode instanceof IClassNode)
+            {
+                String className = ((IClassNode)pnode).getQualifiedName();
+                getModel().getInternalClasses().put(className, mainClassName + "." + className);
+                if (firstInternalContent == null) firstInternalContent = pnode;
+            }
+            else if (pnode instanceof IInterfaceNode)
+            {
+                String className = ((IInterfaceNode)pnode).getQualifiedName();
+                getModel().getInternalClasses().put(className, mainClassName + "." + className);
+                if (firstInternalContent == null) firstInternalContent = pnode;
+            }
             else if (pnode instanceof IFunctionNode)
             {
                 String className = ((IFunctionNode)pnode).getQualifiedName();
                 getModel().getInternalClasses().put(className, mainClassName + "." + className);
+                if (firstInternalContent == null) firstInternalContent = pnode;
             }
             else if (pnode instanceof INamespaceNode)
             {
                 String className = ((INamespaceNode)pnode).getQualifiedName();
                 getModel().getInternalClasses().put(className, mainClassName + "." + className);
+                if (firstInternalContent == null) firstInternalContent = pnode;
             }
             else if (pnode instanceof IVariableNode)
             {
                 String className = ((IVariableNode)pnode).getQualifiedName();
                 getModel().getInternalClasses().put(className, mainClassName + "." + className);
+                if (firstInternalContent == null) firstInternalContent = pnode;
             }
         }
-
+        if (mainClassNameisVar && firstInternalContent != null) {
+            getProblems().add(new FilePrivateItemsWithMainVarWarningProblem(firstInternalContent));
+        }
         packageHeaderEmitter.emit(definition);
+        
     }
 
     @Override
@@ -958,7 +1101,8 @@
     @Override
 	public void emitClosureStart()
     {
-        ICompilerProject project = getWalker().getProject();;
+        if (getDocEmitter() instanceof JSRoyaleDocEmitter && ((JSRoyaleDocEmitter) getDocEmitter()).getSuppressClosure()) return;
+        ICompilerProject project = getWalker().getProject();
         if (project instanceof RoyaleJSProject)
         	((RoyaleJSProject)project).needLanguage = true;
         getModel().needLanguage = true;
@@ -969,6 +1113,7 @@
     @Override
 	public void emitClosureEnd(IASNode node, IDefinition nodeDef)
     {
+        if (getDocEmitter() instanceof JSRoyaleDocEmitter && ((JSRoyaleDocEmitter) getDocEmitter()).getSuppressClosure()) return;
     	write(ASEmitterTokens.COMMA);
     	write(ASEmitterTokens.SPACE);
     	write(ASEmitterTokens.SINGLE_QUOTE);
@@ -980,7 +1125,7 @@
             	String ns = ((INamespaceResolvedReference)((FunctionDefinition)nodeDef).getNamespaceReference()).resolveAETNamespace(getWalker().getProject()).getName();
             	write(ns + "::");
         	}
-    		write(((IIdentifierNode)node).getName());
+    		write(nodeDef.getBaseName());
     	}
     	else if (node.getNodeID() == ASTNodeID.MemberAccessExpressionID)
     		writeChainName(node);
@@ -993,11 +1138,17 @@
     @Override
     public void emitStatement(IASNode node)
     {
-    	// don't emit named local functions as statements
-    	// they are emitted as part of the function block header
-    	if (node.getNodeID() == ASTNodeID.FunctionID)
+    	if (node instanceof IFunctionNode)
     	{
-    		return;
+            IFunctionNode fnode = (IFunctionNode) node;
+            if(fnode.getName().length() > 0)
+            {
+                // don't emit named local functions as statements, if they have
+                // a name. these functions are emitted as part of the function
+                // block header because that is required by JS strict mode.
+                // anonymous functions (functions without a name) are allowed.
+                return;
+            }
     	}
     	super.emitStatement(node);
     }
@@ -1112,10 +1263,10 @@
         		if (EmitterUtils.writeE4xFilterNode(getWalker().getProject(), getModel(), node))
         			write("node.");
             	write("attribute(");
-        		getWalker().walk(parentNode.getRightOperandNode());        		
+        		getWalker().walk(parentNode.getRightOperandNode());
             	write(")");
         	}
-        		
+        	
         	return;
         }
 
@@ -1147,7 +1298,7 @@
 			IDefinition rightDef = rightNode.resolveType(getWalker().getProject());
 			if (rightDef != null)
 			{
-				if (IdentifierNode.isXMLish(rightDef, getWalker().getProject()))
+				if (SemanticUtils.isXMLish(rightDef, getWalker().getProject()))
 				{
 					return isLeftNodeXMLish(leftNode);
 				}
@@ -1167,9 +1318,9 @@
 		{
 			IDefinition leftDef = leftNode.resolveType(getWalker().getProject());
 			if (leftDef != null)
-				return IdentifierNode.isXMLish(leftDef, getWalker().getProject());
+				return SemanticUtils.isXMLish(leftDef, getWalker().getProject());
 		}
-		else if (leftID == ASTNodeID.MemberAccessExpressionID)
+		else if (leftID == ASTNodeID.MemberAccessExpressionID || leftID == ASTNodeID.Op_DescendantsID)
 		{
 			MemberAccessExpressionNode maen = (MemberAccessExpressionNode)leftNode;
 	    	IExpressionNode rightNode = maen.getRightOperandNode();
@@ -1179,7 +1330,7 @@
 				IDefinition rightDef = rightNode.resolveType(getWalker().getProject());
 				if (rightDef != null)
 				{
-					return IdentifierNode.isXMLish(rightDef, getWalker().getProject());
+					return SemanticUtils.isXMLish(rightDef, getWalker().getProject());
 				}
 			}
 			leftNode = maen.getLeftOperandNode();
@@ -1204,7 +1355,7 @@
 			leftNode = (IExpressionNode)(leftNode.getChild(0));
 			IDefinition leftDef = leftNode.resolveType(getWalker().getProject());
 			if (leftDef != null)
-				return IdentifierNode.isXMLish(leftDef, getWalker().getProject());
+				return SemanticUtils.isXMLish(leftDef, getWalker().getProject());
 
 		}
 		else if (leftID == ASTNodeID.E4XFilterID)
@@ -1301,7 +1452,14 @@
     {
 		// See if the left side is XML or XMLList
 		IDefinition leftDef = obj.resolveType(getWalker().getProject());
-		return IdentifierNode.isXMLish(leftDef, getWalker().getProject());
+		if (leftDef == null && obj.getNodeID() == ASTNodeID.MemberAccessExpressionID)
+		{
+			return isXML(((MemberAccessExpressionNode)obj).getLeftOperandNode());
+		}
+		else if (leftDef != null && leftDef.getBaseName().equals("*") && obj instanceof DynamicAccessNode) {
+            return isXML(((DynamicAccessNode)obj).getLeftOperandNode());
+        }
+		return SemanticUtils.isXMLish(leftDef, getWalker().getProject());
     }
 
     public MemberAccessExpressionNode getLastMAEInChain(MemberAccessExpressionNode node)
@@ -1326,21 +1484,50 @@
     @Override
     public void emitTypedExpression(ITypedExpressionNode node)
     {
-        write(JSRoyaleEmitterTokens.VECTOR);
+        ICompilerProject project = getWalker().getProject();
+        if (project instanceof RoyaleJSProject)
+        {
+        	String vectorClassName = ((RoyaleJSProject)project).config == null ? null : ((RoyaleJSProject)project).config.getJsVectorEmulationClass();
+        	if (vectorClassName != null)
+        	{
+        	    if (!vectorClassName.equals("Array"))
+        		    write(vectorClassName);
+        		return;
+        	}
+        }
+        Boolean written = false;
+        if (node instanceof TypedExpressionNode) {
+            startMapping(node);
+            write(ASEmitterTokens.PAREN_OPEN);
+            write(JSRoyaleEmitterTokens.SYNTH_VECTOR);
+            write(ASEmitterTokens.PAREN_OPEN);
+            write(ASEmitterTokens.SINGLE_QUOTE);
+            //the element type of the Vector:
+            write(formatQualifiedName(node.getTypeNode().resolve(project).getQualifiedName()));
+            write(ASEmitterTokens.SINGLE_QUOTE);
+            write(ASEmitterTokens.PAREN_CLOSE);
+            write(ASEmitterTokens.PAREN_CLOSE);
+            endMapping(node);
+            written = true;
+        }
+
+        if (!written) {
+            write(JSRoyaleEmitterTokens.VECTOR);
+        }
         if (getModel().inStaticInitializer)
-        	staticUsedNames.add(JSRoyaleEmitterTokens.LANGUAGE_QNAME.getToken());
+        {
+        	if (!staticUsedNames.contains(JSRoyaleEmitterTokens.LANGUAGE_QNAME.getToken()))
+        		staticUsedNames.add(JSRoyaleEmitterTokens.LANGUAGE_QNAME.getToken());
+        }
         if (project instanceof RoyaleJSProject)
         	((RoyaleJSProject)project).needLanguage = true;
         getModel().needLanguage = true;
     }
     
-	boolean isExternal(String className)
+	boolean isGoogProvided(String className)
 	{
         ICompilerProject project = getWalker().getProject();
-		ICompilationUnit cu = project.resolveQNameToCompilationUnit(className);
-		if (cu == null) return false; // unit testing
-		
-		return ((RoyaleJSProject)project).isExternalLinkage(cu);
+		return ((RoyaleJSProject)project).isGoogProvided(className);
 	}
 
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitterTokens.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitterTokens.java
index 8155c0d..d0ad79f 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitterTokens.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitterTokens.java
@@ -28,9 +28,14 @@
 {
     ROYALE_CLASS_INFO("ROYALE_CLASS_INFO"),
     ROYALE_REFLECTION_INFO("ROYALE_REFLECTION_INFO"),
+    ROYALE_REFLECTION_INFO_GET_SET("get_set"),
+    ROYALE_REFLECTION_INFO_INITIAL_STATICS("statics"),
+    ROYALE_REFLECTION_INFO_COMPILE_TIME_FLAGS("compileFlags"),
     ROYALE_CLASS_INFO_KIND("kind"),
     ROYALE_CLASS_INFO_CLASS_KIND("class"),
     ROYALE_CLASS_INFO_INTERFACE_KIND("interface"),
+    ROYALE_CLASS_INFO_IS_DYNAMIC("isDynamic"),
+    ROYALE_SYNTH_TAG_FIELD_NAME("SYNTH_TAG_FIELD"),
     GOOG_EXPORT_PROPERTY("goog.exportProperty"),
     GOOG_EXPORT_SYMBOL("goog.exportSymbol"),
     INDENT("  "),
@@ -45,7 +50,12 @@
     IGNORE_COERCION("@royaleignorecoercion"),
     IGNORE_IMPORT("@royaleignoreimport"),
     IGNORE_STRING_COERCION("@royalenoimplicitstringconversion"),
+    SUPPRESS_EXPORT("@royalesuppressexport"),
+    SUPPRESS_CLOSURE("@royalesuppressclosure"),
     SUPPRESS_PUBLIC_VAR_WARNING("@royalesuppresspublicvarwarning"),
+    SUPPRESS_COMPLEX_IMPLICIT_COERCION("@royalesuppresscompleximplicitcoercion"),
+    SUPPRESS_RESOLVE_UNCERTAIN("@royalesuppressresolveuncertain"),
+    SUPPRESS_VECTOR_INDEX_CHECK("@royalesuppressvectorindexcheck"),
     DEBUG_COMMENT("@royaledebug"),
     DEBUG_RETURN("if(!goog.DEBUG)return;"),
     PREINCREMENT("preincrement"),
@@ -61,7 +71,10 @@
     SKIP_AS_COERCIONS("skipAsCoercions"),
     SKIP_FUNCTION_COERCIONS("skipFunctionCoercions"),
     JSX("JSX"),
-    VECTOR("org.apache.royale.utils.Language.Vector"),
+    VECTOR(LANGUAGE_QNAME.getToken() + ".Vector"),
+    SYNTH_TYPE(LANGUAGE_QNAME.getToken() + ".synthType"),
+    SYNTH_VECTOR(LANGUAGE_QNAME.getToken() + ".synthVector"),
+    VECTOR_INDEX_CHECK_METHOD_NAME(LANGUAGE_QNAME.getToken() + ".CHECK_INDEX"),
     ;
 
     private String token;
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/utils/DocEmitterUtils.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/utils/DocEmitterUtils.java
index dd9ed44..a188e76 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/utils/DocEmitterUtils.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/utils/DocEmitterUtils.java
@@ -20,6 +20,7 @@
 package org.apache.royale.compiler.internal.codegen.js.utils;
 
 import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleDocEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter;
@@ -27,7 +28,7 @@
 
 public class DocEmitterUtils
 {
-    public static void loadImportIgnores(JSRoyaleEmitter emitter, String doc)
+    public static List<String> loadImportIgnores(JSRoyaleEmitter emitter, String doc)
     {
         ArrayList<String> ignoreList = new ArrayList<String>();
         String ignoreToken = JSRoyaleEmitterTokens.IGNORE_IMPORT.getToken();
@@ -39,11 +40,20 @@
             ignorable = ignorable.substring(0, endIndex);
             ignorable = ignorable.trim();
             ignoreList.add(ignorable);
-            System.out.println("Found ignorable: " + ignorable);
             index = doc.indexOf(ignoreToken, index + endIndex);
         }
         
         // TODO (mschmalle)
         ((JSRoyaleDocEmitter)emitter.getDocEmitter()).setClassIgnoreList(ignoreList);
+        return ignoreList;
+    }
+    
+    
+    public static Boolean hasSuppressExport(JSRoyaleEmitter emitter, String doc)
+    {
+
+        String ignoreToken = JSRoyaleEmitterTokens.SUPPRESS_EXPORT.getToken();
+        int index = doc.indexOf(ignoreToken);
+        return index != -1;
     }
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/utils/EmitterUtils.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/utils/EmitterUtils.java
index 9013dee..eeec0c2 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/utils/EmitterUtils.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/utils/EmitterUtils.java
@@ -22,18 +22,15 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.apache.royale.compiler.constants.IASLanguageConstants;
+import org.apache.royale.compiler.constants.IASLanguageConstants.BuiltinType;
 import org.apache.royale.compiler.definitions.IClassDefinition;
 import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.definitions.IFunctionDefinition;
 import org.apache.royale.compiler.definitions.IFunctionDefinition.FunctionClassification;
-import org.apache.royale.compiler.definitions.INamespaceDefinition;
 import org.apache.royale.compiler.definitions.ITypeDefinition;
 import org.apache.royale.compiler.definitions.IVariableDefinition;
 import org.apache.royale.compiler.internal.codegen.js.JSSessionModel;
@@ -44,14 +41,13 @@
 import org.apache.royale.compiler.internal.definitions.NamespaceDefinition.INamepaceDeclarationDirective;
 import org.apache.royale.compiler.internal.definitions.ParameterDefinition;
 import org.apache.royale.compiler.internal.definitions.VariableDefinition;
-import org.apache.royale.compiler.internal.projects.CompilerProject;
-import org.apache.royale.compiler.internal.scopes.TypeScope;
 import org.apache.royale.compiler.internal.tree.as.ContainerNode;
 import org.apache.royale.compiler.internal.tree.as.NodeBase;
 import org.apache.royale.compiler.internal.tree.as.ParameterNode;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IASNode;
+import org.apache.royale.compiler.tree.as.IAccessorNode;
 import org.apache.royale.compiler.tree.as.IClassNode;
 import org.apache.royale.compiler.tree.as.IContainerNode;
 import org.apache.royale.compiler.tree.as.IDefinitionNode;
@@ -64,6 +60,7 @@
 import org.apache.royale.compiler.tree.as.IScopedNode;
 import org.apache.royale.compiler.tree.as.ITypeNode;
 import org.apache.royale.compiler.tree.as.IUnaryOperatorNode;
+import org.apache.royale.compiler.tree.as.IVariableExpressionNode;
 import org.apache.royale.compiler.tree.as.IVariableNode;
 import org.apache.royale.compiler.utils.NativeUtils;
 
@@ -364,6 +361,7 @@
             else
             {
                 boolean isFileOrPackageMember = false;
+                boolean isLocalFunction = false;
                 if(nodeDef instanceof FunctionDefinition)
                 {
                     FunctionClassification classification = ((FunctionDefinition) nodeDef).getFunctionClassification();
@@ -373,13 +371,20 @@
                         isFileOrPackageMember = true;
                     }
                     else if (!identifierIsMemberAccess && classification == FunctionClassification.CLASS_MEMBER &&
-                    		isClassMember(project, nodeDef, thisClass))
-                    	return true;
+                            isClassMember(project, nodeDef, thisClass))
+                    {
+                        return true;
+                    }
+                    else if (classification == FunctionClassification.LOCAL)
+                    {
+                        isLocalFunction = true;
+                    }
                 }
                 return parentNodeId == ASTNodeID.FunctionCallID
                         && !(nodeDef instanceof AccessorDefinition)
                         && !identifierIsMemberAccess
-                        && !isFileOrPackageMember;
+                        && !isFileOrPackageMember
+                        && !isLocalFunction;
             }
         }
         else
@@ -574,25 +579,22 @@
         result.setParent((NodeBase) argumentsNode.getParent());
         for (int i = 0; i < originalLength; i++)
         {
-            if(i < originalLength)
+            if(i < index)
             {
                 result.addItem((NodeBase) argumentsNode.getChild(i));
             }
             else
             {
-                int j = i;
-                if (i >= index + extraLength)
+            	if (i == index)
                 {
-                    j -= extraLength;
-                    result.addItem((NodeBase) argumentsNode.getChild(j));
+                    for (IASNode node : nodes)
+                    {
+                    	NodeBase n = (NodeBase) node;
+                    	n.setSourcePath(argumentsNode.getSourcePath());
+                    	result.addItem(n);
+                    }
                 }
-                else
-                {
-                    j -= originalLength;
-                    NodeBase node = (NodeBase) nodes[j];
-                    node.setSourcePath(argumentsNode.getSourcePath());
-                    result.addItem(node);
-                }
+                result.addItem((NodeBase) argumentsNode.getChild(i));
             }
         }
         return result;
@@ -604,4 +606,60 @@
                 || node.getContainerType() == IContainerNode.ContainerType.SYNTHESIZED;
     }
 
+    public static boolean needsDefaultValue(IVariableNode node, boolean defaultInitializers, ICompilerProject project)
+    {
+        if (node == null)
+        {
+            return false;
+        }
+        if (node instanceof IParameterNode)
+        {
+            return false;
+        }
+        if (node instanceof IAccessorNode)
+        {
+            return false;
+        }
+        IExpressionNode assignedValueNode = node.getAssignedValueNode();
+        if (assignedValueNode != null)
+        {
+            //already has an assigned value, so it doesn't need to be
+            //hoisted
+            return false;
+        }
+        IASNode parentNode = node.getParent();
+        if (parentNode instanceof IVariableExpressionNode)
+        {
+            //ignore for-in loops
+            return false;
+        }
+        IExpressionNode variableTypeNode = node.getVariableTypeNode();
+        if (variableTypeNode == null)
+        {
+            return false;
+        }
+        IDefinition varTypeDef = variableTypeNode.resolve(project);
+        if (varTypeDef == null)
+        {
+            return false;
+        }
+        if (IASLanguageConstants.ANY_TYPE.equals(varTypeDef.getQualifiedName()))
+        {
+            return false;
+        }
+        if (project.getBuiltinType(BuiltinType.ANY_TYPE).equals(varTypeDef)
+                || project.getBuiltinType(BuiltinType.ANY_TYPE).equals(varTypeDef)
+                || project.getBuiltinType(BuiltinType.ANY_TYPE).equals(varTypeDef))
+        {
+            return false;
+        }
+        if (project.getBuiltinType(BuiltinType.INT).equals(varTypeDef)
+                || project.getBuiltinType(BuiltinType.UINT).equals(varTypeDef))
+        {
+            //always true, regardless of -js-default-initializers
+            return true;
+        }
+        return defaultInitializers;
+    }
+
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/MXMLWriter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/MXMLWriter.java
index 6274d53..9e45aaf 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/MXMLWriter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/MXMLWriter.java
@@ -19,9 +19,7 @@
 
 package org.apache.royale.compiler.internal.codegen.mxml;
 
-import java.io.BufferedOutputStream;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.List;
@@ -72,7 +70,7 @@
 
         try
         {
-            out.write(mxmlEmitter.postProcess(writer.toString()).getBytes());
+            out.write(mxmlEmitter.postProcess(writer.toString()).getBytes("utf8"));
         }
         catch (IOException e)
         {
@@ -82,11 +80,19 @@
         if (sourceMapOut != null)
         {
             String sourceMapFilePath = null;
+            String sourceRoot = null;
             if (sourceMapFile != null)
             {
                 sourceMapFilePath = sourceMapFile.getAbsolutePath();
                 convertMappingSourcePathsToRelative((IMappingEmitter) mxmlEmitter, sourceMapFile);
             }
+            else
+            {
+                sourceRoot = System.getProperty("user.dir");
+                convertMappingSourcePathsToRelative((IMappingEmitter) mxmlEmitter, new File(sourceRoot, "test.js.map"));
+                sourceRoot = convertSourcePathToURI(sourceRoot);
+            }
+            convertMappingSourcePathsToURI((IMappingEmitter) mxmlEmitter);
 
             File compilationUnitFile = new File(compilationUnit.getAbsoluteFilename());
             ISourceMapEmitter sourceMapEmitter = backend.createSourceMapEmitter((IMappingEmitter) mxmlEmitter);
@@ -94,8 +100,8 @@
             {
                 String fileName = compilationUnitFile.getName();
                 fileName = fileName.replace(".mxml", ".js");
-                String sourceMap = sourceMapEmitter.emitSourceMap(fileName, sourceMapFilePath, null);
-                sourceMapOut.write(sourceMap.getBytes());
+                String sourceMap = sourceMapEmitter.emitSourceMap(fileName, sourceMapFilePath, sourceRoot);
+                sourceMapOut.write(sourceMap.getBytes("utf8"));
             } catch (Exception e)
             {
                 e.printStackTrace();
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleCordovaPublisher.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleCordovaPublisher.java
index 38f05a0..975ee45 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleCordovaPublisher.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleCordovaPublisher.java
@@ -19,12 +19,10 @@
 
 package org.apache.royale.compiler.internal.codegen.mxml.royale;
 
-import org.apache.commons.io.FilenameUtils;
 import org.apache.royale.compiler.clients.problems.ProblemQuery;
 import org.apache.royale.compiler.config.Configuration;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
 
-import java.io.File;
 import java.io.IOException;
 
 public class MXMLRoyaleCordovaPublisher extends MXMLRoyalePublisher
@@ -50,12 +48,5 @@
     
     private void createCordovaProjectIfNeeded()
     {
-        // The "intermediate" is the "js-debug" output.
-        final File intermediateDir = outputFolder;
-        final String projectName = FilenameUtils.getBaseName(configuration.getTargetFile());
-
-        // The "release" is the "js-release" directory.
-        File releaseDir = new File(outputParentFolder, ROYALE_RELEASE_DIR_NAME);
-
     }
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java
index 2d1baf3..e06efba 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java
@@ -20,10 +20,6 @@
 package org.apache.royale.compiler.internal.codegen.mxml.royale;
 
 
-import static org.apache.royale.abc.ABCConstants.OP_newarray;
-import static org.apache.royale.abc.ABCConstants.OP_pushstring;
-import static org.apache.royale.abc.ABCConstants.OP_pushtrue;
-
 import java.io.File;
 import java.io.FilterWriter;
 import java.util.ArrayList;
@@ -34,6 +30,7 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+import java.util.Stack;
 
 import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.royale.abc.semantics.MethodInfo;
@@ -50,6 +47,7 @@
 import org.apache.royale.compiler.definitions.IClassDefinition;
 import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.definitions.ITypeDefinition;
+import org.apache.royale.compiler.internal.as.codegen.InstructionListNode;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.databinding.BindingDatabase;
 import org.apache.royale.compiler.internal.codegen.databinding.BindingInfo;
@@ -80,6 +78,7 @@
 import org.apache.royale.compiler.internal.tree.as.MemberAccessExpressionNode;
 import org.apache.royale.compiler.internal.tree.mxml.MXMLDocumentNode;
 import org.apache.royale.compiler.internal.tree.mxml.MXMLFileNode;
+import org.apache.royale.compiler.internal.tree.mxml.MXMLBindingNode;
 import org.apache.royale.compiler.mxml.IMXMLLanguageConstants;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.ASTNodeID;
@@ -184,8 +183,12 @@
         {
         	asEmitterUsedNames.remove(usedName);
         }
-        System.out.println(currentClassName + " as: " + asEmitterUsedNames.toString());
-        System.out.println(currentClassName + " mxml: " + usedNames.toString());
+        RoyaleJSProject fjp = (RoyaleJSProject) getMXMLWalker().getProject();
+        if (fjp.config == null || fjp.config.isVerbose())
+        {
+            System.out.println(currentClassName + " as: " + asEmitterUsedNames.toString());
+            System.out.println(currentClassName + " mxml: " + usedNames.toString());
+        }
         usedNames.addAll(asEmitterUsedNames);
 
         boolean foundXML = false;
@@ -203,14 +206,17 @@
             String line = lines[i];
     		if (stillSearching)
     		{
-                int c = line.indexOf(JSGoogEmitterTokens.GOOG_PROVIDE.getToken());
-                if (c != -1)
+                if (provideIndex == -1 || !sawRequires)
                 {
-                    // if zero requires are found, require Language after the
-                    // call to goog.provide
-                    provideIndex = i + 1;
+                    int c = line.indexOf(JSGoogEmitterTokens.GOOG_PROVIDE.getToken());
+                    if (c != -1)
+                    {
+                        // if zero requires are found, require Language after the
+                        // call to goog.provide
+                        provideIndex = i + 1;
+                    }
                 }
-	            c = line.indexOf(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
+	            int c = line.indexOf(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
 	            if (c > -1)
 	            {
 	                int c2 = line.indexOf(")");
@@ -243,11 +249,15 @@
                             if (subDocumentNames.contains(usedName)) continue;
                             if (royaleProject != null)
                             {
+                                if (!isGoogProvided(usedName))
+                                {
+                                    continue;
+                                }
                             	ICompilationUnit cu = royaleProject.resolveQNameToCompilationUnit(usedName);
-                            	if (cu != null && royaleProject.isExternalLinkage(cu))
-                            		continue;
-                            	if (cu == null)
-                            		System.out.println("didn't find CompilationUnit for " + usedName);
+                                if (cu == null)
+                                {
+                                    System.out.println("didn't find CompilationUnit for " + usedName);
+                                }
                             }
                             namesToAdd.add(usedName);
                         }
@@ -301,14 +311,18 @@
 	            	Set<String> mixins = royaleProject.mixinClassNames;
 	            	if (mixins.size() > 0)
 	            	{
-		            	String mixinInject = "mixins: [";
+		            	String mixinInject = "\"mixins\": [";
 		            	boolean firstOne = true;
 		            	for (String mixin : mixins)
 		            	{
-		            		if (isExternal(mixin))
-		            			continue;
-		            		if (!firstOne)
-		            			mixinInject += ", ";
+                            if (!isGoogProvided(mixin))
+                            {
+                                continue;
+                            }
+                            if (!firstOne)
+                            {
+                                mixinInject += ", ";
+                            }
 		            		mixinInject += mixin;
 		            		firstOne = false;
 		                    StringBuilder appendString = new StringBuilder();
@@ -330,14 +344,18 @@
 	            	Map<String, String> aliases = royaleProject.remoteClassAliasMap;
 	            	if (aliases != null && aliases.size() > 0)
 	            	{
-		            	String aliasInject = sep + "remoteClassAliases: {";
+		            	String aliasInject = sep + "\"remoteClassAliases\": {";
 		            	boolean firstOne = true;
 		            	for (String className : aliases.keySet())
 		            	{
-		            		if (isExternal(className))
-		            			continue;
-		            		if (!firstOne)
-		            			aliasInject += ", ";
+                            if (!isGoogProvided(className))
+                            {
+                                continue;
+                            }
+                            if (!firstOne)
+                            {
+                                aliasInject += ", ";
+                            }
 		            		aliasInject += "\"" + className + "\": ";
 		            		String alias = aliases.get(className);
 		            		aliasInject += "\"" + alias + "\"";
@@ -361,14 +379,16 @@
 	                Collection<String> locales = royaleProject.getLocales();
 	                if (locales.size() > 0)
 	                {
-		            	String localeInject = sep + "compiledLocales: [";
+		            	String localeInject = sep + "\"compiledLocales\": [";
 		            	boolean firstOne = true;
 		            	String[] localeNames = new String[locales.size()];
 		            	locales.toArray(localeNames);
 		            	for (String locale : localeNames)
 		            	{
-		            		if (!firstOne)
-		            			localeInject += ", ";
+                            if (!firstOne)
+                            {
+                                localeInject += ", ";
+                            }
 		            		localeInject += "\"" + locale + "\"";
 		            		firstOne = false;
 		            	}
@@ -380,12 +400,14 @@
 	                List<String> bundles = royaleProject.compiledResourceBundleNames;
 	                if (bundles.size() > 0)
 	                {
-		            	String bundleInject = sep + "compiledResourceBundleNames: [";
+		            	String bundleInject = sep + "\"compiledResourceBundleNames\": [";
 		            	boolean firstOne = true;
 		            	for (String bundle : bundles)
 		            	{
-		            		if (!firstOne)
-		            			bundleInject += ", ";
+                            if (!firstOne)
+                            {
+                                bundleInject += ", ";
+                            }
 		            		bundleInject += "\"" + bundle + "\"";
 		            		firstOne = false;
 		            	}
@@ -482,19 +504,26 @@
         }
 		if (staticUsedNames.size() > 0)
 		{
-			StringBuilder sb = new StringBuilder();
-			sb.append(JSGoogEmitterTokens.ROYALE_STATIC_DEPENDENCY_LIST.getToken());
-			boolean firstDependency = true;
-			for (String staticName : staticUsedNames)
+			if (staticUsedNames.size() > 1 ||
+					!staticUsedNames.get(0).equals(currentClassName))
 			{
-				if (!firstDependency)
-					sb.append(",");
-				firstDependency = false;
-				sb.append(staticName);
+				StringBuilder sb = new StringBuilder();
+				sb.append(JSGoogEmitterTokens.ROYALE_STATIC_DEPENDENCY_LIST.getToken());
+				boolean firstDependency = true;
+				for (String staticName : staticUsedNames)
+				{
+					if (currentClassName.equals(staticName))
+						continue;
+					
+					if (!firstDependency)
+						sb.append(",");
+					firstDependency = false;
+					sb.append(staticName);
+				}
+				sb.append("*/");
+				finalLines.add(provideIndex, sb.toString());
+	            addLineToMappings(provideIndex);
 			}
-			sb.append("*/");
-			finalLines.add(provideIndex, sb.toString());
-            addLineToMappings(provideIndex);
 		}
 
     	return Joiner.on("\n").join(finalLines);
@@ -739,6 +768,7 @@
     {
         ArrayList<MXMLDescriptorSpecifier> oldDescriptorTree;
         MXMLDescriptorSpecifier oldPropertiesTree;
+        MXMLDescriptorSpecifier oldStateOverrides;
         ArrayList<MXMLEventSpecifier> oldEvents;
         ArrayList<IMXMLScriptNode> oldScripts;
         ArrayList<MXMLDescriptorSpecifier> oldCurrentInstances;
@@ -767,7 +797,9 @@
         currentInstances = new ArrayList<MXMLDescriptorSpecifier>();
         oldCurrentPropertySpecifiers = currentPropertySpecifiers;
         currentPropertySpecifiers = new ArrayList<MXMLDescriptorSpecifier>();
-
+        oldStateOverrides = currentStateOverrides;
+        currentStateOverrides = new MXMLDescriptorSpecifier();
+        
         oldEventCounter = eventCounter;
         eventCounter = 0;
         oldIdCounter = idCounter;
@@ -820,6 +852,7 @@
 
         descriptorTree = oldDescriptorTree;
         propertiesTree = oldPropertiesTree;
+        currentStateOverrides = oldStateOverrides;
         events = oldEvents;
         scripts = oldScripts;
         currentInstances = oldCurrentInstances;
@@ -1174,24 +1207,18 @@
             data.isStatic = false;
             data.declaredBy = cdef.getQualifiedName();
         }
-
-
-        for (MXMLEventSpecifier event : events)
-        {
-        	PackageFooterEmitter.MethodData data = asEmitter.packageFooterEmitter.new MethodData();
-        	methodData.add(data);
-        	data.name = event.eventHandler;
-        	data.type = ASEmitterTokens.VOID.getToken();
-    	    data.declaredBy = cdef.getQualifiedName();
-        }
+        
         ArrayList<IMetaTagNode> metadataTagNodes = new ArrayList<IMetaTagNode>();
         for (IMXMLMetadataNode metadataTag : metadataNodes)
         {
         	IMetaTagNode[] tags = metadataTag.getMetaTagNodes();
-        	for (IMetaTagNode tag : tags)
-        	{
-        		metadataTagNodes.add(tag);
-        	}
+        	//tags (MetaTagNodes) can be null if the parent node is empty (or content is commented out)
+        	if (tags != null) {
+                for (IMetaTagNode tag : tags)
+                {
+                    metadataTagNodes.add(tag);
+                }
+            }
         }
         IMetaTagNode[] metaDataTags = new IMetaTagNode[metadataTagNodes.size()];
 
@@ -1202,6 +1229,11 @@
         		accessorData,
                 methodData,
                 metadataTagNodes.toArray(metaDataTags));
+	
+		asEmitter.packageFooterEmitter.emitReflectionRegisterInitialStaticFields(
+				formatQualifiedName(cdef.getQualifiedName()),
+				cdef);
+        
         asEmitter.packageFooterEmitter.emitExportProperties(
                 formatQualifiedName(cdef.getQualifiedName()),
                 exportProperties,
@@ -1303,8 +1335,8 @@
     private void outputBindingInfoAsData(String cname, BindingDatabase bindingDataBase)
     {
         IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker())
-        .getASEmitter();
-
+                .getASEmitter();
+        
         writeNewline("/**");
         writeNewline(" * @export"); // must export or else GCC will remove it
         writeNewline(" */");
@@ -1313,9 +1345,11 @@
 
         Set<BindingInfo> bindingInfo = bindingDataBase.getBindingInfo();
         writeNewline(bindingInfo.size() + ","); // number of bindings
-
+        boolean hadOutput = false;
         for (BindingInfo bi : bindingInfo)
         {
+            if (hadOutput) writeNewline(ASEmitterTokens.COMMA.getToken());
+            hadOutput = true;
             String s;
             IMXMLNode node = bi.node;
             if (node instanceof IMXMLSingleDataBindingNode)
@@ -1325,7 +1359,7 @@
             	IDefinition bdef = sbdn.getExpressionNode().resolve(project);
             	if (bdef != null)
             	{
-	            	IDefinition cdef = bdef.getParent();
+	            	//IDefinition cdef = bdef.getParent();
 	            	project.addExportedName(/*cdef.getQualifiedName() + "." + */bdef.getBaseName());
             	}
             }
@@ -1362,8 +1396,11 @@
 	                String[] parts = s.split("\\.");
 	                write(ASEmitterTokens.SQUARE_OPEN.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() +
 	                        bi.classDef.getQualifiedName() + ASEmitterTokens.DOUBLE_QUOTE.getToken());
-	                usedNames.add(bi.classDef.getQualifiedName());
-	                staticUsedNames.add(bi.classDef.getQualifiedName());
+	                String qname = bi.classDef.getQualifiedName();
+	                if (!usedNames.contains(qname))
+	                	usedNames.add(qname);
+	                if (!staticUsedNames.contains(qname))
+	                	staticUsedNames.add(qname);
 	                int n = parts.length;
 	                for (int i = 1; i < n; i++)
 	                {
@@ -1391,19 +1428,19 @@
                         ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
 
             IExpressionNode destNode = bi.getExpressionNodeForDestination();
-            if (destNode != null)
+            s = bi.getDestinationString();
+            if (destNode != null && s == null)
             {
                 StringBuilder sb = new StringBuilder();
-                sb.append(generateSetterFunction(destNode));
+                sb.append(generateSetterFunction(bi, destNode));
                 writeNewline(sb.toString() + ASEmitterTokens.COMMA.getToken());
             }
             else
                 writeNewline(ASEmitterTokens.NULL.getToken() + ASEmitterTokens.COMMA.getToken());
 
-            s = bi.getDestinationString();
             if (s == null)
             {
-                writeNewline(ASEmitterTokens.NULL.getToken() + ASEmitterTokens.COMMA.getToken());
+                write(ASEmitterTokens.NULL.getToken());
             }
             else if (s.contains("."))
             {
@@ -1416,17 +1453,22 @@
                     String part = parts[i];
                     write(", " + ASEmitterTokens.DOUBLE_QUOTE.getToken() + part + ASEmitterTokens.DOUBLE_QUOTE.getToken());
                 }
-                writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
+                write(ASEmitterTokens.SQUARE_CLOSE.getToken());
             }
             else
-                writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + s +
-                        ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
+                write(ASEmitterTokens.DOUBLE_QUOTE.getToken() + s +
+                        ASEmitterTokens.DOUBLE_QUOTE.getToken());
+            
         }
         Set<Entry<Object, WatcherInfoBase>> watcherChains = bindingDataBase.getWatcherChains();
-
+        
         if (watcherChains != null)
         {
             int count = watcherChains.size();
+            if (hadOutput) {
+                if (count > 0) writeNewline(ASEmitterTokens.COMMA);
+                else writeNewline();
+            }
             for (Entry<Object, WatcherInfoBase> entry : watcherChains)
             {
                 count--;
@@ -1434,37 +1476,70 @@
                 encodeWatcher(watcherInfoBase);
                 if (count > 0) writeNewline(ASEmitterTokens.COMMA);
             }
+        } else {
+            if (hadOutput) writeNewline();
         }
 
         writeNewline( ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.SEMICOLON.getToken());
     }
 
-    private String generateSetterFunction(IExpressionNode destNode) {
+    private String generateSetterFunction(BindingInfo bi, IExpressionNode destNode) {
         IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker())
         	.getASEmitter();
-		String body = asEmitter.stringifyNode(destNode);
-
 		StringBuilder sb = new StringBuilder();
 		sb.append("function (value) { ");
-		int lastGet = body.lastIndexOf("get_");
-		int lastDot = body.lastIndexOf(".");
-		if (lastDot == lastGet - 1)
+		if (destNode instanceof InstructionListNode)
 		{
-			String object = body.substring(0, lastDot);
-			String getter = body.substring(lastDot);
-			String setter = getter.replace("get_", "set_");
-			setter = setter.replace("()", "(value)");
-			body = object + setter;
-			sb.append(body);
+			sb.append(generateDestExpression(bi));
 		}
 		else
 		{
+			String body = asEmitter.stringifyNode(destNode);
 			sb.append(body);
 			sb.append(" = value;");
 		}
-		sb.append(";}");
+		sb.append("}");
 		return sb.toString();
 	}
+    
+    String generateDestExpression(BindingInfo bi)
+    {
+    	StringBuilder sb = new StringBuilder();
+    	MXMLBindingNode node = (MXMLBindingNode)bi.node;
+    	IMXMLBindingAttributeNode destNode = node.getDestinationAttributeNode();
+    	Stack<IASNode> nodeStack = new Stack<IASNode>();
+    	nodeStack.push(node);
+    	IASNode parentNode = node.getParent();
+    	while (!(parentNode instanceof IMXMLInstanceNode))
+    	{
+    		nodeStack.push(parentNode);
+    		parentNode = parentNode.getParent();
+    	}
+    	boolean isXML = parentNode instanceof IMXMLXMLNode;
+    	sb.append("this.");
+    	sb.append(((IMXMLInstanceNode)parentNode).getEffectiveID());
+    	while (nodeStack.size() > 0)
+    	{
+    		IASNode childNode = nodeStack.pop();
+    		int n = parentNode.getChildCount();
+    		int i = 0;
+    		for (; i < n; i++)
+    		{
+    			if (childNode == parentNode.getChild(i))
+    				break;
+    		}
+    		assert i < n;
+    		sb.append("[" + new Integer(i).toString() + "]" );
+    		parentNode = childNode;
+    	}
+    	if (isXML)
+    	{
+    		sb.append(".setAttribute('" + destNode.getName() + "', value);" );
+    	}
+    	else
+    		sb.append("." + destNode.getName() + " = value;");
+    	return sb.toString();
+    }
 
 	private void encodeWatcher(WatcherInfoBase watcherInfoBase)
     {
@@ -1480,19 +1555,22 @@
             FunctionWatcherInfo functionWatcherInfo = (FunctionWatcherInfo)watcherInfoBase;
 
             writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + functionWatcherInfo.getFunctionName() +
-                    ASEmitterTokens.DOUBLE_QUOTE.getToken());
+                    ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
             IExpressionNode params[] = functionWatcherInfo.params;
             StringBuilder sb = new StringBuilder();
             sb.append("function() { return [");
             boolean firstone = true;
             for (IExpressionNode param : params)
             {
-                if (firstone)
-                    firstone = false;
-                sb.append(ASEmitterTokens.COMMA.getToken());
+                if (!firstone)
+                {
+                    sb.append(ASEmitterTokens.COMMA.getToken());
+                }
+                firstone = false;
                 sb.append(asEmitter.stringifyNode(param));
             }
             sb.append("]; },");
+            writeNewline(sb.toString());
             outputEventNames(functionWatcherInfo.getEventNames());
             outputBindings(functionWatcherInfo.getBindings());
         }
@@ -1762,7 +1840,7 @@
     	int n = 0;
         for (MXMLDescriptorSpecifier instance : instances)
         {
-            if (instance.id != null)
+            if (instance.id != null || instance.hasLocalId)
             {
             	n++;
             }
@@ -1997,7 +2075,7 @@
             propertiesTree.propertySpecifiers.add(currentInstance);
         }
 
-        instances.add(currentInstance);
+        addInstanceIfNeeded(instances, currentInstance);
 
         IMXMLPropertySpecifierNode[] pnodes = node.getPropertySpecifierNodes();
         if (pnodes != null)
@@ -2092,7 +2170,17 @@
         }
     }
 
-    public void emitPropertyOverride(IMXMLPropertySpecifierNode propertyNode)
+    private void addInstanceIfNeeded(
+			ArrayList<MXMLDescriptorSpecifier> instances2,
+			MXMLDescriptorSpecifier currentInstance) {
+    	for (MXMLDescriptorSpecifier instance : instances2)
+    		if (instance.id != null && currentInstance.id != null && instance.id.equals(currentInstance.id))
+    			return;
+        instances.add(currentInstance);
+
+	}
+
+	public void emitPropertyOverride(IMXMLPropertySpecifierNode propertyNode)
     {
         RoyaleProject project = (RoyaleProject) getMXMLWalker().getProject();
         Name propertyOverride = project.getPropertyOverrideClassName();
@@ -2720,7 +2808,7 @@
             }
         }
         writeNewline("/**");
-        writeNewline(" * Generated by Apache Royale Compiler from " + sourceName);
+        writeNewline(" * Generated by Apache Royale Compiler from " + sourceName.replace('\\', '/'));
         writeNewline(" * " + cname);
         writeNewline(" *");
         writeNewline(" * @fileoverview");
@@ -2954,16 +3042,23 @@
     	if (subDocumentNames.contains(name))
     		return documentDefinition.getQualifiedName() + "." + name;
         if (NativeUtils.isJSNative(name)) return name;
-    	if (inStaticInitializer)
-    		if (!staticUsedNames.contains(name) && !NativeUtils.isJSNative(name) && !isExternal(name))
-    			staticUsedNames.add(name);
+        if (inStaticInitializer)
+        {
+            if (!staticUsedNames.contains(name) && !NativeUtils.isJSNative(name) && isGoogProvided(name))
+            {
+                staticUsedNames.add(name);
+            }
+        }
 
-		if (useName && !usedNames.contains(name) && !isExternal(name))
-			usedNames.add(name);
+        if (useName && !usedNames.contains(name) && isGoogProvided(name))
+        {
+            usedNames.add(name);
+        }
      	return name;
     }
 
-    private void emitComplexInitializers(IASNode node)
+    @SuppressWarnings("incomplete-switch")
+	private void emitComplexInitializers(IASNode node)
     {
     	int n = node.getChildCount();
     	for (int i = 0; i < n; i++)
@@ -2993,16 +3088,17 @@
     	                    write(ASEmitterTokens.MEMBER_ACCESS);
     	                    JSRoyaleEmitter fjs = (JSRoyaleEmitter) ((IMXMLBlockWalker) getMXMLWalker())
     	                    .getASEmitter();
-    		    	        ICompilerProject project = getMXMLWalker().getProject();
+    	                    
+    	                    ICompilerProject project = getMXMLWalker().getProject();
     	                    String qname = varnode.getName();
-    	                	if (varDef != null && varDef.isPrivate() && project.getAllowPrivateNameConflicts())
-    	                		qname = fjs.formatPrivateName(varDef.getParent().getQualifiedName(), qname);
+    	                		if (varDef != null && varDef.isPrivate() && project.getAllowPrivateNameConflicts())
+    	                			qname = fjs.formatPrivateName(varDef.getParent().getQualifiedName(), qname);
     	                    write(qname);
     	                    if (schildID == ASTNodeID.BindableVariableID && !varnode.isConst())
     	                    	write("_"); // use backing variable
     	                    write(ASEmitterTokens.SPACE);
     	                    writeToken(ASEmitterTokens.EQUAL);
-    	                    fjs.getWalker().walk(vnode);
+                            fjs.emitAssignmentCoercion(vnode, varnode.getVariableTypeNode().resolve(getMXMLWalker().getProject()));
     	                    write(ASEmitterTokens.SEMICOLON);
 
     			        }
@@ -3121,9 +3217,15 @@
     	if (instanceNode instanceof IMXMLStringNode)
     	{
     		IMXMLStringNode stringNode = (IMXMLStringNode)instanceNode;
-            IMXMLLiteralNode valueNode = (IMXMLLiteralNode)(stringNode.getExpressionNode());
-            Object value = valueNode.getValue();
-            return objectToString(value);
+    		IASNode vNode = stringNode.getExpressionNode();
+    		if (vNode instanceof IMXMLLiteralNode)
+    		{
+	            IMXMLLiteralNode valueNode = (IMXMLLiteralNode)vNode;
+	            Object value = valueNode.getValue();
+	            return objectToString(value);
+    		}
+    		else
+    			return "''";
     	}
     	return "";
     }
@@ -3176,14 +3278,11 @@
         //System.out.println("mxml implements "+list);
         interfaceList = list.toString();
     }
-
-	boolean isExternal(String className)
+    
+	boolean isGoogProvided(String className)
 	{
         ICompilerProject project = getMXMLWalker().getProject();
-		ICompilationUnit cu = project.resolveQNameToCompilationUnit(className);
-		if (cu == null) return false; // unit testing
-
-		return ((RoyaleJSProject)project).isExternalLinkage(cu);
+		return ((RoyaleJSProject)project).isGoogProvided(className);
 	}
 
 	@Override
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyalePublisher.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyalePublisher.java
index 9cd88ad..0407b31 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyalePublisher.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyalePublisher.java
@@ -18,6 +18,7 @@
  */
 package org.apache.royale.compiler.internal.codegen.mxml.royale;
 
+import com.google.common.io.Files;
 import com.google.javascript.jscomp.SourceFile;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.FilenameUtils;
@@ -29,7 +30,6 @@
 import org.apache.royale.compiler.clients.problems.ProblemQuery;
 import org.apache.royale.compiler.codegen.js.IJSPublisher;
 import org.apache.royale.compiler.config.Configuration;
-import org.apache.royale.compiler.css.ICSSDocument;
 import org.apache.royale.compiler.css.ICSSPropertyValue;
 import org.apache.royale.compiler.definitions.metadata.IMetaTag;
 import org.apache.royale.compiler.filespecs.IFileSpecification;
@@ -45,7 +45,6 @@
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
 import org.apache.royale.compiler.internal.scopes.ASProjectScope.DefinitionPromise;
 import org.apache.royale.compiler.internal.targets.ITargetAttributes;
-import org.apache.royale.compiler.tree.metadata.IMetaTagNode;
 import org.apache.royale.compiler.utils.JSClosureCompilerWrapper;
 import org.apache.royale.swc.ISWC;
 import org.apache.royale.swc.ISWCFileEntry;
@@ -54,6 +53,7 @@
 import java.io.*;
 import java.net.URL;
 import java.net.URLDecoder;
+import java.nio.charset.Charset;
 import java.util.*;
 
 public class MXMLRoyalePublisher extends JSGoogPublisher implements IJSPublisher
@@ -100,6 +100,7 @@
     private String outputPathParameter;
     private String moduleOutput;
     private boolean useStrictPublishing;
+    private List<String> additionalHTML = new ArrayList<String>();
 
     private GoogDepsWriter getGoogDepsWriter(File intermediateDir, 
     										String mainClassQName, 
@@ -189,11 +190,17 @@
         // The source directory is the source path entry containing the Main class.
         List<File> sourcePaths = project.getSourcePath();
         String targetFile = configuration.getTargetFile().toLowerCase();
-    	System.out.println("find project folder for " + targetFile);
+    	if (googConfiguration.isVerbose())
+        {
+            System.out.println("find project folder for " + targetFile);
+        }
         File imageSrcDir = null;
         for (File sp : sourcePaths)
         {
-        	System.out.println("checking source path " + sp.getAbsolutePath());
+        	if (googConfiguration.isVerbose())
+            {
+                System.out.println("checking source path " + sp.getAbsolutePath());
+            }
         	String lowercasePath = sp.getAbsolutePath().toLowerCase();
         	if (targetFile.startsWith(lowercasePath))
         		imageSrcDir = sp;
@@ -201,7 +208,10 @@
         if (imageSrcDir == null)
         {
         	imageSrcDir = new File(configuration.getTargetFile()).getAbsoluteFile().getParentFile();
-        	System.out.println("not found on source path, using parent file " + imageSrcDir.getAbsolutePath());
+        	if (googConfiguration.isVerbose())
+            {
+                System.out.println("not found on source path, using parent file " + imageSrcDir.getAbsolutePath());
+            }
         }
         final String projectName = FilenameUtils.getBaseName(configuration.getTargetFile());
         String qName = null;
@@ -351,7 +361,7 @@
         // the application will not be able to run.
         for(SourceFile closureSourceFile : closureSourceFiles) {
             FileUtils.write(new File(new File(intermediateDir, "library/closure"),
-                    closureSourceFile.getName()), closureSourceFile.getCode());
+                    closureSourceFile.getName()), closureSourceFile.getCode(), Charset.forName("utf8"));
         }
         closureSourceFiles = closureFilesInOrder(intermediateDir + "/library/closure/", closureSourceFiles, "goog.events.EventTarget");
 
@@ -360,18 +370,24 @@
         // Prepare the closure compilation.
         /////////////////////////////////////////////////////////////////////////////////
 
-        JSClosureCompilerWrapper compilerWrapper = new JSClosureCompilerWrapper(googConfiguration.getJSCompilerOptions());
-
-
-        /////////////////////////////////////////////////////////////////////////////////
-        // Add all the closure lib files to the compilation unit.
-        /////////////////////////////////////////////////////////////////////////////////
-
-        for (SourceFile closureSourceFile : closureSourceFiles) {
-            compilerWrapper.addJSSourceFile(closureSourceFile);
+        JSClosureCompilerWrapper compilerWrapper = null;
+        if (configuration.release())
+        {
+            compilerWrapper = new JSClosureCompilerWrapper(googConfiguration.getJSCompilerOptions());
         }
 
-        writeExportedNames(compilerWrapper);
+        if (compilerWrapper != null)
+        {
+            /////////////////////////////////////////////////////////////////////////////////
+            // Add all the closure lib files to the compilation unit.
+            /////////////////////////////////////////////////////////////////////////////////
+
+            for (SourceFile closureSourceFile : closureSourceFiles) {
+                compilerWrapper.addJSSourceFile(closureSourceFile);
+            }
+
+            writeExportedNames(compilerWrapper);
+        }
 
         /////////////////////////////////////////////////////////////////////////////////
         // Add all the externs to the compilation
@@ -379,6 +395,7 @@
 
         // Iterate over all swc dependencies and add all the externs they contain.
         // (Externs are located in a "externs" directory in the root of the SWC)
+        Set<ISWC> swcExterns = project.swcExterns;
         List<ISWC> swcs = project.getLibraries();
         List<ISWC> allswcs = new ArrayList<ISWC>();
         allswcs.addAll(swcs);
@@ -396,19 +413,27 @@
                         InputStream is = fileEntry.createInputStream();
                         String code = IOUtils.toString(is, "UTF-8");
                         is.close();
-                        JarSourceFile externFile = new JarSourceFile(key, code,true);
-                        System.out.println("using extern: " + key);
-                        compilerWrapper.addJSExternsFile(externFile);
+                        
+                        if (compilerWrapper != null)
+                        {
+                            JarSourceFile externFile = new JarSourceFile(key, code,true);
+                            if (googConfiguration.isVerbose())
+                            {
+                                System.out.println("using extern: " + key);
+                            }
+                            compilerWrapper.addJSExternsFile(externFile);
+                        }
 
-                        // Write the extern into the filesystem.
-                        // FIXME: I don't know why we need to do this.
-                        //FileUtils.write(new File(intermediateDir, key), externFile.getCode());
+                        if (swcExterns.contains(swc))
+                        {
+                            List<String> lines = IOUtils.readLines(new StringReader(code));
+                            collectAdditionalHTML(lines, swc.getSWCFile().getAbsolutePath() + ":" + key);
+                        }
                     }
                 }
             }
         }
 
-
         /////////////////////////////////////////////////////////////////////////////////
         // Add all files generated by the compiler to the compilation unit.
         /////////////////////////////////////////////////////////////////////////////////
@@ -419,28 +444,44 @@
         // js files of used dependencies.
         ArrayList<String> sourceExternFiles = new ArrayList<String>();
         ArrayList<String> fileList = gdw.getListOfFiles(project, sourceExternFiles, problems);
+        if (fileList == null)
+            return false; // some error occurred
+        
         for (String sourceExtern : project.sourceExterns)
         {
-        	String sourceExternFileName = sourceExtern.replace(".", "/") + ".js";
-        	File sourceExternFile = new File(intermediateDir, sourceExternFileName);
-        	if (sourceExternFile.exists())
-        	{
-        		String sourceExternPath = sourceExternFile.getAbsolutePath();
-        		if (!sourceExternFiles.contains(sourceExternPath))
-        			sourceExternFiles.add(sourceExternPath);
-        	}
+            String sourceExternFileName = sourceExtern.replace(".", "/") + ".js";
+            File sourceExternFile = new File(intermediateDir, sourceExternFileName);
+            if (sourceExternFile.exists())
+            {
+                String sourceExternPath = sourceExternFile.getAbsolutePath();
+                if (!sourceExternFiles.contains(sourceExternPath))
+                    sourceExternFiles.add(sourceExternPath);
+            }
         }
-        if (fileList == null)
-        	return false; // some error occurred
-        for (String file : fileList) {
-            compilerWrapper.addJSSourceFile(file);
-            System.out.println("using source file: " + file);            
+        if (compilerWrapper != null)
+        {
+            for (String file : fileList)
+            {
+                compilerWrapper.addJSSourceFile(file);
+                if (googConfiguration.isVerbose())
+                {            
+                    System.out.println("using source file: " + file);
+                }
+            }
         }
-        for (String file : sourceExternFiles) {
-        	compilerWrapper.addJSExternsFile(file);
-            System.out.println("using extern file: " + file);            
+        for (String file : sourceExternFiles)
+        {
+            if (compilerWrapper != null)
+            {
+                compilerWrapper.addJSExternsFile(file);
+                if (googConfiguration.isVerbose())
+                {
+                    System.out.println("using extern file: " + file);
+                }
+            }
+            collectFileAdditionalHTML(file);
         }
-
+        additionalHTML.addAll(gdw.additionalHTML);
 
         /////////////////////////////////////////////////////////////////////////////////
         // Generate the index.html for loading the application.
@@ -450,14 +491,23 @@
         // is generated here so it can be used for outputting the html templates.
         String depsFileData = gdw.generateDeps(project, problems);
 
+        // FOR MODULES: this generate inject_html lines for js to be added to __deps.js
+        String moduleAdditionHTML = "";
+
         if (project.isModule(mainClassQName))
         {
+            for (String s : additionalHTML)
+            {
+                moduleAdditionHTML += "document.head.innerHTML += '"+ s.trim() + "';";
+            }
+            
         	// need better test someday
         	depsFileData += "\ngoog.require('" + mainClassQName + "');\n";
-            writeFile(new File(intermediateDir, projectName + "__deps.js"), depsFileData, false);
-            Set<String> provideds = computeProvideds(depsFileData);
-            compilerWrapper.setProvideds(provideds);
+            writeFile(new File(intermediateDir, projectName + "__deps.js"), depsFileData + moduleAdditionHTML + "\n", false);
             gdw.needCSS = true;
+            if (configuration.release()) {
+            	writeFile(new File(releaseDir, projectName + ".js"), moduleAdditionHTML, false);
+            }
         }
         else
         {
@@ -465,17 +515,17 @@
 	        // Create the index.html for the debug-js version.
 	        if (!((JSGoogConfiguration)configuration).getSkipTranspile()) {
 	            if (template != null) {
-	                writeTemplate(template, "intermediate", projectName, mainClassQName, intermediateDir, depsFileData, gdw.additionalHTML);
+	                writeTemplate(template, "intermediate", projectName, mainClassQName, intermediateDir, depsFileData, additionalHTML);
 	            } else {
-	                writeHTML("intermediate", projectName, mainClassQName, intermediateDir, depsFileData, gdw.additionalHTML);
+	                writeHTML("intermediate", projectName, mainClassQName, intermediateDir, depsFileData, additionalHTML);
 	            }
 	        }
 	        // Create the index.html for the release-js version.
 	        if (configuration.release()) {
 	            if (template != null) {
-	                writeTemplate(template, "release", projectName, mainClassQName, releaseDir, depsFileData, gdw.additionalHTML);
+	                writeTemplate(template, "release", projectName, mainClassQName, releaseDir, depsFileData, additionalHTML);
 	            } else {
-	                writeHTML("release", projectName, mainClassQName, releaseDir, null, gdw.additionalHTML);
+	                writeHTML("release", projectName, mainClassQName, releaseDir, null, additionalHTML);
 	            }
 	        }
         }        
@@ -500,40 +550,35 @@
         // If we are doing a release build, let the closure compiler do it's job.
         /////////////////////////////////////////////////////////////////////////////////
 
-        if (configuration.release()) {
+        if (compilerWrapper != null) {
+            boolean ok = true;
             final File projectReleaseMainFile = new File(releaseDir, outputFileName);
             compilerWrapper.setOptions(projectReleaseMainFile.getCanonicalPath(), useStrictPublishing, !googConfiguration.getRemoveCirculars(), projectName);
             compilerWrapper.targetFilePath = projectReleaseMainFile.getCanonicalPath();
             compilerWrapper.setSourceMap(googConfiguration.getSourceMap());
+            compilerWrapper.setVerbose(googConfiguration.isVerbose());
 
-            compilerWrapper.compile();
+            ok = compilerWrapper.compile();
+
+            // FOR MODULES: add moduleAdditionHTML to main js release file too
+            if (project.isModule(mainClassQName))
+            {
+                StringBuilder appendString = new StringBuilder();
+                appendString.append(moduleAdditionHTML);
+                writeFile(projectReleaseMainFile, appendString.toString(), true);
+            }
 
             appendSourceMapLocation(projectReleaseMainFile, projectName);
+            
+            if (ok)
+                System.out.println("The project '" + projectName + "' has been successfully compiled and optimized.");
         }
-
-        // if (ok)
-        System.out.println("The project '" + projectName + "' has been successfully compiled and optimized.");
+        else
+        	System.out.println("The project '" + projectName + "' has been successfully compiled.");
 
         return true;
     }
 
-    private Set<String> computeProvideds(String data)
-    {
-    	HashSet<String> set = new HashSet<String>();
-    	String[] lines = data.split("\n");
-    	for (String line : lines)
-    	{
-    		int c = line.indexOf("['");
-    		if (c != -1)
-    		{
-	    		int c2 = line.indexOf("'", c + 2);
-	    		String name = line.substring(c + 2, c2);
-	    		set.add(name);
-    		}
-    	}
-    	return set;
-    }
-    
     protected List<SourceFile> closureFilesInOrder(String path, List<SourceFile> files, String entryPoint)
     {
     	ArrayList<String> sortedFiles = new ArrayList<String>();
@@ -545,7 +590,10 @@
     		if ((sourceFile.getOriginalPath().endsWith("goog/deps.js") || sourceFile.getOriginalPath().endsWith("goog\\deps.js")) &&
         		!(sourceFile.getOriginalPath().endsWith("third_party/goog/deps.js") || sourceFile.getOriginalPath().endsWith("third_party\\goog\\deps.js")))
     			depsFile = sourceFile;
-    		System.out.println("originalPath: " + sourceFile.getOriginalPath());
+            if (googConfiguration.isVerbose())
+            {
+                System.out.println("originalPath: " + sourceFile.getOriginalPath());
+            }
     		fileMap.put(sourceFile.getOriginalPath(), sourceFile);
     	}
     	
@@ -557,10 +605,13 @@
             while (true)
             {
 	            String line = in.readLine();
+	            if (line == null)
+	            	break;
 	            if (line.startsWith("//") || line.trim().length() == 0)
 	            	continue;
 	            deps.add(line);
             }
+            in.close();
         }
         catch (Exception e)
         {
@@ -579,7 +630,10 @@
         for (int i = n - 1; i >= 0; i--)
         {
         	String fileName = sortedFiles.get(i);
-        	System.out.println("sorted filename: " + fileName);
+        	if (googConfiguration.isVerbose())
+            {
+                System.out.println("sorted filename: " + fileName);
+            }
         	if (seen.contains(fileName)) 
         		continue;
         	seen.add(fileName);
@@ -591,6 +645,84 @@
         }
         return list;
     }
+
+    private void collectFileAdditionalHTML(String filePath)
+    {
+        List<String> fileLines;
+        try
+        {
+            fileLines = Files.readLines(new File(filePath), Charset.forName("utf8"));
+        }
+        catch(IOException e)
+        {
+            return;
+        }
+        collectAdditionalHTML(fileLines, filePath);
+    }
+
+    private void collectAdditionalHTML(List<String> lines, String key)
+    {
+        boolean inDocComment = false;
+        boolean inConstructor = false;
+        boolean inInjectHTML = false;
+	    for (int i = 0; i < lines.size(); i++)
+	    {
+            String line = lines.get(i);
+            if (inDocComment)
+            {
+                if (inInjectHTML)
+                {
+                    if (line.indexOf("</inject_html>") > -1)
+                    {
+                        inInjectHTML = false;
+                        continue;
+                    }
+                    line = line.trim();
+                    if (line.startsWith("*"))
+                        line = line.substring(1);
+                    additionalHTML.add(line);
+                    continue;
+                }
+                int c = line.indexOf("<inject_html>");
+                if (c != -1)
+                {
+                    inInjectHTML = true;
+                    continue;
+                }
+                if (!inConstructor)
+                {
+                    c = line.indexOf("@constructor");
+                    if(c != -1)
+                    {
+                        inConstructor = true;
+                        continue;
+                    }
+                }
+                c = line.indexOf("*/");
+                if(c != -1)
+                {
+                    if(inConstructor)
+                    {
+                        //we're done
+                        break;
+                    }
+                    inInjectHTML = false;
+                    inDocComment = false;
+                    inConstructor = false;
+                }
+
+            }
+            else
+            {
+                int c = line.indexOf("/**");
+                if(c != -1)
+                {
+                    inDocComment = true;
+                    continue;
+                }
+            }
+        }
+    }
     
     private void sortClosureFile(List<String> deps, String entryPoint, List<String> sortedFiles)
     {
@@ -609,23 +741,23 @@
     	for (String dep : deps)
     	{
     		int open = dep.indexOf("[");
-    		int close = dep.indexOf("]");
+    		int close = dep.indexOf("]", open + 1);
 			String list = dep.substring(open + 1, close);
 			String[] parts = list.split(",");
-			ArrayList<String> provideds = new ArrayList<String>();
 			for (String part : parts)
 			{
 				part = part.trim();
-				if (part.startsWith("'"))
-					part = part.substring(1, part.length() - 1);
-				provideds.add(part);    				
+                if (part.startsWith("'"))
+                {
+                    part = part.substring(1, part.length() - 1);
+                }
+                if(part.equals(name))
+                {
+                    open = dep.indexOf("'");
+                    close = dep.indexOf("'", open + 1);
+                    return dep.substring(open + 1, close);    
+                }
 			}
-    		if (provideds.contains(name))
-    		{
-    			open = dep.indexOf("'");
-    			close = dep.indexOf("'", open + 1);
-    			return dep.substring(open + 1, close);    			
-    		}
     	}
     	return null;
     }
@@ -635,35 +767,40 @@
     	for (String dep : deps)
     	{
     		int open = dep.indexOf("[");
-    		int close = dep.indexOf("]");
+    		int close = dep.indexOf("]", open + 1);
 			String list = dep.substring(open + 1, close);
 			String[] parts = list.split(",");
-			ArrayList<String> provideds = new ArrayList<String>();
 			for (String part : parts)
 			{
 				part = part.trim();
-				if (part.startsWith("'"))
-					part = part.substring(1, part.length() - 1);
-				provideds.add(part);    				
+                if (part.startsWith("'"))
+                {
+                    part = part.substring(1, part.length() - 1);
+                }
+                
+                if(part.equals(name))
+                {
+                    open = dep.indexOf("[", close + 1);
+                    close = dep.indexOf("]", open + 1);
+                    if (open + 1 == close)
+                    {
+                        return null;
+                    }
+                    String list2 = dep.substring(open + 1, close);
+                    String[] parts2 = list2.split(",");
+                    ArrayList<String> reqs = new ArrayList<String>();
+                    for (String part2 : parts2)
+                    {
+                        part2 = part2.trim();
+                        if (part2.startsWith("'"))
+                        {
+                            part2 = part2.substring(1, part2.length() - 1);
+                        }
+                        reqs.add(part2);    				
+                    }
+                    return reqs;
+                }				
 			}
-    		if (provideds.contains(name))
-    		{
-    			open = dep.indexOf("[", close + 1);
-    			close = dep.indexOf("]", open + 1);
-    			if (open + 1 == close)
-    				return null;
-    			String list2 = dep.substring(open + 1, close);
-    			String[] parts2 = list2.split(",");
-    			ArrayList<String> reqs = new ArrayList<String>();
-    			for (String part : parts2)
-    			{
-    				part = part.trim();
-    				if (part.startsWith("'"))
-    					part = part.substring(1, part.length() - 1);
-    				reqs.add(part);    				
-    			}
-    			return reqs;
-    		}
     	}
     	return null;
     }    
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogCompcConfiguration.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogCompcConfiguration.java
index c5581b0..46af0bd 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogCompcConfiguration.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogCompcConfiguration.java
@@ -423,6 +423,26 @@
     }
 
     //
+    // 'export-protected-symbols'
+    //
+
+    private boolean exportProtectedSymbols = false;
+
+    public boolean getExportProtectedSymbols()
+    {
+        return exportProtectedSymbols;
+    }
+
+    @Config
+    @Mapping("export-protected-symbols")
+    public void setExportProtectedSymbols(ConfigurationValue cv, boolean value)
+            throws ConfigurationException
+    {
+    	exportProtectedSymbols = value;
+    }
+
+    
+    //
     // 'warn-public-vars'
     //
 
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogConfiguration.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogConfiguration.java
index b6c6d7b..d4e5328 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogConfiguration.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogConfiguration.java
@@ -46,7 +46,7 @@
  * configure() method of {@link MXMLJSC}.
  * <p>
  * This class inherits all compiler arguments from the MXMLC compiler.
- * 
+ *
  * @author Erik de Bruin
  */
 public class JSGoogConfiguration extends JSConfiguration
@@ -428,6 +428,26 @@
 
     
     //
+    // 'export-protected-symbols'
+    //
+
+    private boolean exportProtectedSymbols = false;
+
+    public boolean getExportProtectedSymbols()
+    {
+        return exportProtectedSymbols;
+    }
+
+    @Config
+    @Mapping("export-protected-symbols")
+    public void setExportProtectedSymbols(ConfigurationValue cv, boolean value)
+            throws ConfigurationException
+    {
+    	exportProtectedSymbols = value;
+    }
+
+    
+    //
     // 'warn-public-vars'
     //
 
@@ -446,6 +466,69 @@
     	warnPublicVars = value;
     }
 
+    // 'externs-report' option
+    //
+
+    private String externsReportFileName = null;
+
+    public File getExternsReport()
+    {
+        return externsReportFileName != null ? new File(externsReportFileName) : null;
+    }
+
+    /**
+     * Prints externs information to the specified output file. This file is an Google Closure Compiler externs file that contains
+     * all of the public and protected APIs in the final SWF file. The file format output
+     * by this command can be used to write a file for input to the {@code -js-compiler-options="--externs <path-to-this-file>"} option.
+     */
+    @Config(advanced = true)
+    @Mapping("externs-report")
+    @Arguments("filename")
+    public void setExternsReport(ConfigurationValue cv, String filename)
+    {
+        this.externsReportFileName = getOutputPath(cv, filename);
+    }
     
+    
+    /**
+     * Support for reflection data output to represent selected config options
+     * that were used when compiling
+     * @return an integer representation of bit flags representing
+     */
+    public int getReflectionFlags() {
+        int ret = 0;
+        final int WITH_DEFAULT_INITIALIZERS = 1;
+        final int HAS_KEEP_AS3_METADATA = 2;
+        final int HAS_KEEP_CODE_WITH_METADATA = 4;
+        final int HAS_EXPORT_PUBLIC_SYMBOLS = 8;
+        final int EXPORT_PROTECTED_SYMBOLS = 16;
+    
+        if (getJsDefaultInitializers()) ret |= WITH_DEFAULT_INITIALIZERS;
+        if (getCompilerKeepAs3Metadata().size() > 0) ret |= HAS_KEEP_AS3_METADATA;
+        if (getCompilerKeepCodeWithMetadata().size() > 0) ret |= HAS_KEEP_CODE_WITH_METADATA;
+        if (getExportPublicSymbols()) ret |= HAS_EXPORT_PUBLIC_SYMBOLS;
+        if (getExportProtectedSymbols()) ret |= EXPORT_PROTECTED_SYMBOLS;
+        
+        return ret;
+    }
+
+    //
+    // 'inline-constants'
+    //
+
+    private boolean inlineConstants = false;
+
+    public boolean getInlineConstants()
+    {
+        return inlineConstants;
+    }
+
+    @Config
+    @Mapping("inline-constants")
+    public void setInlineConstants(ConfigurationValue cv, boolean value)
+            throws ConfigurationException
+    {
+    	inlineConstants = value;
+    }
 
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/graph/GoogDepsWriter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/graph/GoogDepsWriter.java
index b538f13..7c8d1e1 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/graph/GoogDepsWriter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/graph/GoogDepsWriter.java
@@ -28,6 +28,8 @@
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -37,6 +39,7 @@
 import org.apache.royale.compiler.clients.problems.ProblemQuery;
 import org.apache.royale.compiler.common.DependencyType;
 import org.apache.royale.compiler.common.DependencyTypeSet;
+import org.apache.royale.compiler.config.CompilerDiagnosticsConstants;
 import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
 import org.apache.royale.compiler.internal.driver.js.JSCompilationUnit;
 import org.apache.royale.compiler.internal.driver.js.goog.JSGoogConfiguration;
@@ -44,8 +47,9 @@
 import org.apache.royale.compiler.internal.projects.DefinitionPriority;
 import org.apache.royale.compiler.internal.projects.DependencyGraph;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
-import org.apache.royale.compiler.problems.MainDefinitionQNameProblem;
 import org.apache.royale.compiler.problems.FileNotFoundProblem;
+import org.apache.royale.compiler.problems.MainDefinitionQNameProblem;
+import org.apache.royale.compiler.problems.UnexpectedExceptionProblem;
 import org.apache.royale.compiler.units.ICompilationUnit;
 import org.apache.royale.swc.ISWC;
 import org.apache.royale.swc.ISWCFileEntry;
@@ -64,12 +68,17 @@
 		this.moduleOutput = config.getModuleOutput();
 		this.mainName = mainClassName;
 		removeCirculars = config.getRemoveCirculars();
+		sourceMaps = config.getSourceMap();
 		otherPaths = config.getSDKJSLib();
+		verbose = config.isVerbose();
 		otherPaths.add(new File(outputFolder.getParent(), "royale/Royale/src").getPath());
 		this.swcs = swcs;
-		for (ISWC swc : swcs)
+		if (verbose)
 		{
-			System.out.println("using SWC: " + swc.getSWCFile().getAbsolutePath());
+			for (ISWC swc : swcs)
+			{
+				System.out.println("using SWC: " + swc.getSWCFile().getAbsolutePath());
+			}
 		}
 	}
 	
@@ -78,13 +87,15 @@
 	private String outputFolderPath;
 	private String mainName;
 	private List<String> otherPaths;
-	private List<String> sourceExternFiles;
 	private List<ISWC> swcs;
 	private boolean removeCirculars = false;
+	private boolean sourceMaps = false;
+	private boolean verbose = false;
 	private ArrayList<GoogDep> dps;
 	private DependencyGraph graph;
 	private CompilerProject project;
 	private ArrayList<String> staticInitializers;
+	private ArrayList<String> staticInitializerOwners;
 	
 	private HashMap<String, GoogDep> depMap = new HashMap<String,GoogDep>();
 	private HashMap<String, ICompilationUnit> requireMap = new HashMap<String, ICompilationUnit>();
@@ -96,7 +107,6 @@
 	{
 		this.project = project;
 		this.problems = problems;
-		this.sourceExternFiles = sourceExternFiles;
 
 		if (dps == null)
 		{
@@ -143,6 +153,8 @@
 	    		return "";
 	    	dps = sort();
 	    }
+	    ArrayList<String> usedDeps = new ArrayList<String>();
+	    ArrayList<String> addedDeps = new ArrayList<String>();
 	    StringBuilder sb = new StringBuilder();
 		int n = dps.size();
 		for (int i = n - 1; i >= 0; i--)
@@ -150,29 +162,29 @@
 			GoogDep gd = dps.get(i);
 			if (!isGoogClass(gd.className)) 
 			{
+				addedDeps.add(gd.filePath);
 				if (removeCirculars)
 				{
 					ArrayList <String> deps = new ArrayList<String>();
-					if (gd.fileInfo.impls != null)
-						deps.addAll(gd.fileInfo.impls);
-					if (gd.fileInfo.staticDeps != null)
-					{
-						for (String dep : gd.fileInfo.staticDeps)
-						{
-							if (!deps.contains(dep))
-								deps.add(dep);
-						}
-					}
-					sb.append("goog.addDependency('").append(relativePath(gd.filePath)).append("', ['")
-						.append(gd.className).append("'], [")
-						.append(getDependencies(deps))
-						.append("]);\n");
+					computeDeps(deps, gd, usedDeps);
+					sb.append("goog.addDependency('")
+						.append(relativePath(gd.filePath))
+						.append("', ['")
+						.append(gd.className)
+						.append("'], [");
+					appendDependencies(deps, sb);
+					sb.append("]);\n");
 				}
 				else
-					sb.append("goog.addDependency('").append(relativePath(gd.filePath)).append("', ['")
-					.append(gd.className).append("'], [")
-					.append(getDependencies(gd.deps))
-					.append("]);\n");					
+				{
+					sb.append("goog.addDependency('")
+						.append(relativePath(gd.filePath))
+						.append("', ['")
+						.append(gd.className)
+						.append("'], [");
+					appendDependencies(gd.deps, sb);
+					sb.append("]);\n");
+				}
 			}
 		}
 		if (removeCirculars)
@@ -182,19 +194,40 @@
 			mainDeps.append("goog.addDependency('").append(relativePath(mainDep.filePath)).append("', ['")
 								.append(mainDep.className).append("'], [");
 			ArrayList<String> restOfDeps = new ArrayList<String>();
-			restOfDeps.addAll(mainDep.deps);
+			for (String dep: mainDep.deps)
+			{
+				if (isGoogProvided(dep))
+				{
+					restOfDeps.add(dep);
+				}
+			}
+			if (mainDep.fileInfo.impls != null)
+			{
+				for (String dep: mainDep.fileInfo.impls)
+				{
+					if (isGoogProvided(dep))
+					{
+						restOfDeps.add(dep);
+					}
+				}				
+			}
 	        DependencyTypeSet dependencyTypes = DependencyTypeSet.allOf();
 			// get the list of all units not referenced by other units
 			for (GoogDep gd : depMap.values())
 			{
+				if (usedDeps.contains(gd.className))
+					continue;
+				
 				if (gd.className.equals(mainName)) 
 				{
 					if (gd.fileInfo.impls != null)
 					{
 						for (String d : gd.fileInfo.impls)
 						{
-							if (!restOfDeps.contains(d) && !gd.fileInfo.isExtern && !isExternal(d))
+							if (!restOfDeps.contains(d) && !gd.fileInfo.isExtern && isGoogProvided(d) && !usedDeps.contains(d))
+							{
 								restOfDeps.add(d);
+							}
 						}
 					}
 					continue;
@@ -202,18 +235,23 @@
 				ICompilationUnit unit = requireMap.get(gd.className);
 				if (unit == null)
 				{
-					if (!restOfDeps.contains(gd.className) && !gd.fileInfo.isExtern && !isExternal(gd.className))
+					if (!restOfDeps.contains(gd.className) && !gd.fileInfo.isExtern && isGoogProvided(gd.className) && !usedDeps.contains(gd.className))
+					{
 						restOfDeps.add(gd.className);
+					}
 					continue;
 				}
 				Set<ICompilationUnit> deps = graph.getDirectReverseDependencies(unit, dependencyTypes);
 				if (deps.size() == 0)
 				{
-					if (!restOfDeps.contains(gd.className) && !gd.fileInfo.isExtern && !isExternal(gd.className))
+					if (!restOfDeps.contains(gd.className) && !gd.fileInfo.isExtern && isGoogProvided(gd.className) && !usedDeps.contains(gd.className))
+					{
 						restOfDeps.add(gd.className);
+					}
 				}
 			}
-			mainDeps.append(getDependencies(restOfDeps)).append("]);\n");
+			appendDependencies(restOfDeps, mainDeps);
+			mainDeps.append("]);\n");
 			sb.insert(0, mainDeps);
 			sb.insert(0, "// generated by Royale\n");
 			for (String dep : restOfDeps)
@@ -226,16 +264,43 @@
 					problems.add(new FileNotFoundProblem(dep));
 					continue;
 				}
-				sb.append("goog.addDependency('").append(relativePath(gd.filePath)).append("', ['")
-				.append(gd.className).append("'], [")
-				.append((gd.fileInfo.impls != null) ? getDependencies(gd.fileInfo.impls) : "")
-				.append("]);\n");
+				if (addedDeps.contains(gd.filePath))
+					continue;
+				ArrayList<String> deps = new ArrayList<String>();
+				computeDeps(deps, gd, usedDeps);
+				sb.append("goog.addDependency('")
+					.append(relativePath(gd.filePath))
+					.append("', ['")
+					.append(gd.className)
+					.append("'], [");
+				appendDependencies(deps, sb);
+				sb.append("]);\n");
 			}
 			addRestOfDeps(mainDep, restOfDeps);
 		}
 		return sb.toString();
 	}
 	
+	private void computeDeps(ArrayList<String> deps, GoogDep gd, ArrayList<String> usedDeps) {
+		if (gd.fileInfo.impls != null)
+		{
+			deps.addAll(gd.fileInfo.impls);
+			for (String dep : gd.fileInfo.impls)
+				if (!usedDeps.contains(dep))
+					usedDeps.add(dep);
+		}
+		if (gd.fileInfo.staticDeps != null)
+		{
+			for (String dep : gd.fileInfo.staticDeps)
+			{
+				if (!deps.contains(dep))
+					deps.add(dep);
+				if (!usedDeps.contains(dep))
+					usedDeps.add(dep);
+			}
+		}
+	}
+
 	private boolean isGoogClass(String className)
 	{
 	    return className.startsWith("goog.");
@@ -244,6 +309,7 @@
 	private boolean buildDB()
 	{
 		staticInitializers = new ArrayList<String>();
+		staticInitializerOwners = new ArrayList<String>();
 		
 		graph = new DependencyGraph();
 		if (isGoogClass(mainName))
@@ -251,7 +317,7 @@
 			problems.add(new MainDefinitionQNameProblem("Google Closure Library", mainName));
 			return false;
 		}
-		if (isExternal(mainName))
+		if (!isGoogProvided(mainName))
 		{
 			problems.add(new MainDefinitionQNameProblem("External Libraries", mainName));
 			return false;
@@ -259,27 +325,48 @@
 		addDeps(mainName);
 		return true;
 	}
-	
-    public ArrayList<String> additionalHTML = new ArrayList<String>();
     
-    private HashMap<String, GoogDep> visited = new HashMap<String, GoogDep>();
+	private HashMap<String, GoogDep> visited = new HashMap<String, GoogDep>();
+	
+	public ArrayList<String> additionalHTML = new ArrayList<String>();
     
 	private ArrayList<GoogDep> sort()
 	{
 		// first, promote all dependencies of classes used in static initializers to
 		// the level of static dependencies since their constructors will be
-		// run early
-		for (String staticClass: staticInitializers)
+		// run early.  This may need to be a full transitive walk someday.
+		// This is because we move many goog.requires from the various classes
+		// to the main app when removing circulars.  We only keep goog.requires
+		// that Closure Compiler cares about, which are requires for @extends
+		// and @implements.  However, as classes required by the application get
+		// loaded, their static initializers will fail if we haven't already goog.required
+		// the classes used by these static initializers, so we have to keep goog.requires
+		// used by these static initializers in the class files.
+		int n = staticInitializers.size();
+		for (int i = 0; i < n; i++)
 		{
+			String staticClass = staticInitializers.get(i);
+			String staticOwner = staticInitializerOwners.get(i);
 			GoogDep info = depMap.get(staticClass);
-			if (info != null && info.fileInfo != null && info.fileInfo.deps != null)
+			GoogDep ownerInfo = depMap.get(staticOwner);
+			if (info != null && info.fileInfo != null && info.fileInfo.deps != null && 
+					ownerInfo != null && ownerInfo.fileInfo != null)
 			{
-				if (info.fileInfo.staticDeps == null)
-					info.fileInfo.staticDeps = new ArrayList<String>();
+				if (ownerInfo.fileInfo.staticDeps == null)
+					ownerInfo.fileInfo.staticDeps = new ArrayList<String>();
 				for (String dep : info.fileInfo.deps)
 				{
-					if (!info.fileInfo.staticDeps.contains(dep))
-						info.fileInfo.staticDeps.add(dep);
+					if (!ownerInfo.fileInfo.staticDeps.contains(dep) 
+							&& !isGoogClass(dep)
+							&& !dep.equals(staticOwner))
+					{
+						ownerInfo.fileInfo.staticDeps.add(dep);
+						if (verbose)
+						{
+							System.out.println(staticClass + " used in static initializer of " + staticOwner + " so make " + dep + " a static dependency");
+						}
+						// all things added here should get added to graph in sortFunction
+					}
 				}
 			}
 		}
@@ -294,7 +381,38 @@
 			roots.add(mainUnit);
 			requireMap.remove(mainName);
 			
+			if ((CompilerDiagnosticsConstants.diagnostics & CompilerDiagnosticsConstants.GOOG_DEPS) == CompilerDiagnosticsConstants.GOOG_DEPS)
+			{
+				Collection<ICompilationUnit> units = graph.getCompilationUnits();
+				System.out.println("Contents of graph:");
+				for (ICompilationUnit unit : units)
+				{
+					try {
+						System.out.println(unit.getQualifiedNames().toString());
+					} catch (InterruptedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}					
+				}
+			}
 			List<ICompilationUnit> order = graph.topologicalSort(requireMap.values());
+			if (graph.lastCircularDependencyException != null)
+			{
+				problems.add(new UnexpectedExceptionProblem(graph.lastCircularDependencyException));
+			}
+			if ((CompilerDiagnosticsConstants.diagnostics & CompilerDiagnosticsConstants.GOOG_DEPS) == CompilerDiagnosticsConstants.GOOG_DEPS)
+			{
+				System.out.println("Contents of graph in order:");
+				for (ICompilationUnit unit : order)
+				{
+					try {
+						System.out.println(unit.getQualifiedNames().toString());
+					} catch (InterruptedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}					
+				}
+			}
 			ArrayList<GoogDep> depsInOrder = new ArrayList<GoogDep>();
 			for (ICompilationUnit unit : order)
 			{
@@ -303,13 +421,17 @@
 				GoogDep dep = depMap.get(name);
 				if (dep == null)
 				{
-					System.out.println("No GoogDep for " + name);
-					//added this to prevent a NullPointerException when the
-					//GoogDep is null. -JT
-					problems.add(new FileNotFoundProblem(name));
-					continue;
+					if (isGoogProvided(name))
+					{
+						System.out.println("No GoogDep for " + name);
+						//added this to prevent a NullPointerException when the
+						//GoogDep is null. -JT
+						problems.add(new FileNotFoundProblem(name));
+						continue;
+					}
 				}
-				depsInOrder.add(dep);
+				else
+					depsInOrder.add(dep);
 			}
 			return depsInOrder;
 		}
@@ -321,16 +443,17 @@
 		visited.put(current.className, current);
 		
 		if (removeCirculars)
+		{
 			removeRequires(current);
-        System.out.println("Dependencies calculated for '" + current.className + "'");
+		}
+		if (verbose)
+		{
+			System.out.println("Dependencies calculated for '" + current.className + "'");
+		}
 
 		ICompilationUnit unit = null;
 		
 		if (removeCirculars)
-			if (current.fileInfo.deps == null)
-				return;
-		
-		if (removeCirculars)
 		{
 			unit = requireMap.get(current.className);
 			if (unit == null)
@@ -340,24 +463,10 @@
 				requireMap.put(current.className, unit);
 				requireMap2.put(unit, current.className);
 			}
-			if (current.fileInfo.staticDeps != null && removeCirculars)
-			{
-				for (String staticDep : current.fileInfo.staticDeps)
-				{
-					ICompilationUnit base = requireMap.get(staticDep);
-					if (base == null)
-					{
-						base = new JSCompilationUnit(project, staticDep, DefinitionPriority.BasePriority.SOURCE_LIST, staticDep);
-						graph.addCompilationUnit(base);
-						requireMap.put(staticDep, base);
-						requireMap2.put(base, staticDep);
-					}
-					System.out.println(current.className + " static initialization depends on " + staticDep);
-					graph.addDependency(unit, base, DependencyType.INHERITANCE);
-					
-				}
-			}
+			if (current.fileInfo.deps == null)
+				return;
 		}
+		
 		ArrayList<String> impls = current.fileInfo.impls != null ? current.fileInfo.impls : null;
 		if (impls != null)
 		{
@@ -378,7 +487,10 @@
 								requireMap.put(className, base);
 								requireMap2.put(base, className);
 							}
-							System.out.println(current.className + " depends on " + className);
+							if (verbose)
+							{
+								System.out.println(current.className + " depends on " + className);
+							}
 							graph.addDependency(unit, base, DependencyType.INHERITANCE);
 						}
 						if (!visited.containsKey(className))
@@ -389,10 +501,32 @@
 				}
 			}
 		}
+		if (removeCirculars)
+		{
+			if (current.fileInfo.staticDeps != null && removeCirculars)
+			{
+				for (String staticDep : current.fileInfo.staticDeps)
+				{
+					ICompilationUnit base = requireMap.get(staticDep);
+					if (base == null)
+					{
+						base = new JSCompilationUnit(project, staticDep, DefinitionPriority.BasePriority.SOURCE_LIST, staticDep);
+						graph.addCompilationUnit(base);
+						requireMap.put(staticDep, base);
+						requireMap2.put(base, staticDep);
+					}
+					if (verbose)
+					{
+						System.out.println(current.className + " static initialization depends on " + staticDep);
+					}
+					graph.addDependency(unit, base, DependencyType.INHERITANCE);
+				}
+			}
+		}
 		ArrayList<String> deps = current.deps;
 		for (String className : deps)
 		{
-			if (!isGoogClass(className))
+			if (!isGoogClass(className) && isGoogProvided(className))
 			{
 				GoogDep gd = depMap.get(className);
 				if (gd == null)
@@ -414,31 +548,62 @@
         List<String> fileLines;
 		try {
 			File mainFile = new File(main.filePath);
-			fileLines = Files.readLines(mainFile, Charset.defaultCharset());
+			fileLines = Files.readLines(mainFile, Charset.forName("utf8"));
 
 			SourceMapConsumerV3 sourceMapConsumer = null;
-			File sourceMapFile = new File(main.filePath + ".map");
-			if (sourceMapFile.exists())
+			File sourceMapFile = null;
+			if (sourceMaps)
 			{
-				String sourceMapContents = FileUtils.readFileToString(sourceMapFile);
-				sourceMapConsumer = new SourceMapConsumerV3();
-				try
+				sourceMapFile = new File(main.filePath + ".map");
+				if (sourceMapFile.exists())
 				{
-					sourceMapConsumer.parse(sourceMapContents);
-				}
-				catch(SourceMapParseException e)
-				{
-					sourceMapConsumer = null;
+					String sourceMapContents = FileUtils.readFileToString(sourceMapFile, Charset.forName("utf8"));
+					sourceMapConsumer = new SourceMapConsumerV3();
+					try
+					{
+						sourceMapConsumer.parse(sourceMapContents);
+					}
+					catch(SourceMapParseException e)
+					{
+						sourceMapConsumer = null;
+					}
 				}
 			}
 
+			// first scan requires in case this is a module and some have been externed
+			int j = main.fileInfo.googProvideLine + 1;
+			while (j < fileLines.size() && !fileLines.get(j).contains(JSGoogEmitterTokens.GOOG_REQUIRE.getToken()))
+			{
+				j++;
+			}
+			while (j < fileLines.size() && fileLines.get(j).contains(JSGoogEmitterTokens.GOOG_REQUIRE.getToken()))
+			{
+				String line = fileLines.get(j);
+				int c = line.indexOf(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
+				int c2 = line.indexOf(")");
+                String s = line.substring(c + 14, c2 - 1);
+                if (!isGoogProvided(s))
+                {
+                	fileLines.remove(j);
+					sourceMapConsumer = removeLineFromSourceMap(sourceMapConsumer, mainFile.getName(), j);
+                }
+				else
+				{
+					j++;
+				}
+			}
+			
 			int n = restOfDeps.size();
 			for (int i = n - 1; i >= 0; i--)
 			{
 				String dep = restOfDeps.get(i);
-				//if (!main.deps.contains(dep))
-					fileLines.add(main.fileInfo.googProvideLine + 1, JSGoogEmitterTokens.GOOG_REQUIRE.getToken() + "('" + dep + "');");
-					sourceMapConsumer = addLineToSourceMap(sourceMapConsumer, mainFile.getName(), main.fileInfo.googProvideLine + 1);
+				StringBuilder lineBuilder = new StringBuilder();
+				lineBuilder.append(JSGoogEmitterTokens.GOOG_REQUIRE.getToken())
+					.append("('")
+					.append(dep)
+					.append("');");
+				fileLines.add(main.fileInfo.googProvideLine + 1, lineBuilder.toString());
+				sourceMapConsumer = addLineToSourceMap(sourceMapConsumer, mainFile.getName(), main.fileInfo.googProvideLine + 1);
 			}
 
 			PrintWriter out = new PrintWriter(new FileWriter(mainFile));  
@@ -446,7 +611,7 @@
             {
                 out.println(s);
             }
-            out.close();
+			out.close();
 
 			if (sourceMapConsumer != null)
 			{
@@ -464,8 +629,10 @@
 	
 	private void addDeps(String className)
 	{
-		if (depMap.containsKey(className) || isGoogClass(className) || isExternal(className))
+		if (depMap.containsKey(className) || isGoogClass(className) || !isGoogProvided(className))
+		{
 			return;
+		}
 		
 		// build goog dependency list
 		GoogDep gd = new GoogDep();
@@ -478,7 +645,7 @@
 		depMap.put(gd.className, gd);
         List<String> fileLines;
 		try {
-			fileLines = Files.readLines(new File(gd.filePath), Charset.defaultCharset());
+			fileLines = Files.readLines(new File(gd.filePath), Charset.forName("utf8"));
             FileInfo fi = getFileInfo(fileLines, className);
 			gd.fileInfo = fi;
 		} catch (IOException e) {
@@ -504,6 +671,19 @@
 	        			gd.fileInfo.provides.contains(dep)) continue;
 	            addDeps(dep);
 	        }
+	        if (gd.fileInfo.staticDeps != null)
+	        {
+		        for (String dep : gd.fileInfo.staticDeps)
+		        {
+		        	if (!gd.deps.contains(dep))
+		        	{
+		        		gd.deps.add(dep);
+		        		if (gd.fileInfo.provides != null &&
+		        			gd.fileInfo.provides.contains(dep)) continue;
+		        		addDeps(dep);
+		        	}
+		        }
+	        }
 		}
 	}
 	
@@ -516,22 +696,26 @@
         {
 			gd = depMap.get(className);
 			File depFile = new File(gd.filePath);
-            List<String> fileLines = Files.readLines(depFile, Charset.defaultCharset());
+            List<String> fileLines = Files.readLines(depFile, Charset.forName("utf8"));
 			ArrayList<String> finalLines = new ArrayList<String>();
 			
 			SourceMapConsumerV3 sourceMapConsumer = null;
-			File sourceMapFile = new File(gd.filePath + ".map");
-			if (sourceMapFile.exists())
+			File sourceMapFile = null;
+			if (sourceMaps)
 			{
-				String sourceMapContents = FileUtils.readFileToString(sourceMapFile);
-				sourceMapConsumer = new SourceMapConsumerV3();
-				try
+				sourceMapFile = new File(gd.filePath + ".map");
+				if (sourceMapFile.exists())
 				{
-					sourceMapConsumer.parse(sourceMapContents);
-				}
-				catch(SourceMapParseException e)
-				{
-					sourceMapConsumer = null;
+					String sourceMapContents = FileUtils.readFileToString(sourceMapFile, Charset.forName("utf8"));
+					sourceMapConsumer = new SourceMapConsumerV3();
+					try
+					{
+						sourceMapConsumer.parse(sourceMapContents);
+					}
+					catch(SourceMapParseException e)
+					{
+						sourceMapConsumer = null;
+					}
 				}
 			}
             
@@ -539,8 +723,11 @@
         	StringBuilder sb = new StringBuilder();
         	sb.append(JSGoogEmitterTokens.ROYALE_DEPENDENCY_LIST.getToken());
         	
+        	ArrayList<String> writtenRequires = new ArrayList<String>();
+//        	int staticDepsLine = -1;
+        	int lastRequireLine = -1;
             FileInfo fi = gd.fileInfo;
-            int suppressCount = 0;
+//            int suppressCount = 0;
             int i = 0;
             int stopLine = fi.constructorLine;
             if (fi.constructorLine == -1) // standalone functions
@@ -552,18 +739,26 @@
                     int c = line.indexOf(JSGoogEmitterTokens.ROYALE_DEPENDENCY_LIST.getToken());
                     if (c > -1)
                     	return; // already been processed
+//                    c = line.indexOf(JSGoogEmitterTokens.ROYALE_STATIC_DEPENDENCY_LIST.getToken());
+//                    if (c > -1)
+//                    	staticDepsLine = i;
                     c = line.indexOf(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
                     if (c > -1)
                     {
+                    	lastRequireLine = i;
                         int c2 = line.indexOf(")");
                         String s = line.substring(c + 14, c2 - 1);
-                        if ((gd.fileInfo.impls == null || !gd.fileInfo.impls.contains(s)) &&
-                        		(gd.fileInfo.staticDeps == null || !gd.fileInfo.staticDeps.contains(s)))
+                        if (((gd.fileInfo.impls == null || !gd.fileInfo.impls.contains(s)) &&
+                        		(gd.fileInfo.staticDeps == null || !gd.fileInfo.staticDeps.contains(s))) ||
+                        		!isGoogProvided(s))
                         {
                         	// don't remove the require if some class needs it at static initialization
                         	// time
-                        	suppressCount++;
-                        	System.out.println(gd.filePath + " removing require: " + s);
+//                        	suppressCount++;
+							if (verbose)
+							{
+								System.out.println(gd.filePath + " removing require: " + s);
+							}
                     		if (!firstDependency)
                     			sb.append(",");
                     		sb.append(s);
@@ -571,11 +766,40 @@
 							sourceMapConsumer = removeLineFromSourceMap(sourceMapConsumer, depFile.getName(), finalLines.size());
                         	continue;
 	                    }
+                        else
+                        {
+                        	writtenRequires.add(s);
+                        }
                     }
             	}
-                finalLines.add(line);
+				finalLines.add(line);
+				//no need to call addLineToSourceMap here because we're
+				//populating finalLines for the first time
                 i++;
             }
+            // add any static deps not already listed that were added by static initializers;
+            if (gd.fileInfo.staticDeps != null)
+            {
+    			if (lastRequireLine == -1)
+					lastRequireLine = gd.fileInfo.googProvideLine + 1;
+            	for (String dep : gd.fileInfo.staticDeps)
+            	{
+            		if (!writtenRequires.contains(dep) && isGoogProvided(dep))
+            		{
+						StringBuilder lineBuilder = new StringBuilder();
+						lineBuilder.append(JSGoogEmitterTokens.GOOG_REQUIRE.getToken())
+							.append("('")
+							.append(dep)
+							.append("');");
+            			finalLines.add(lastRequireLine++, lineBuilder.toString());
+						sourceMapConsumer = addLineToSourceMap(sourceMapConsumer, new File(gd.filePath).getName(), lastRequireLine);
+            			if (verbose)
+						{
+							System.out.println("adding require for static dependency " + dep + " to " + className);
+						}
+            		}
+				}
+            }
             //if (suppressCount > 0)
             //{
             	if (fi.suppressLine > 0)
@@ -655,7 +879,7 @@
 			sourceMapConsumer = addLineToSourceMap(sourceMapConsumer, depFile.getName(), gd.fileInfo.googProvideLine + 1);
 
 			PrintWriter out = new PrintWriter(new FileWriter(depFile));  
-            for (String s : finalLines)
+			for (String s : finalLines)
             {
                 out.println(s);
             }
@@ -708,6 +932,7 @@
 	{
 		final SourceMapGeneratorV3 generator = new SourceMapGeneratorV3();
 		final SourceMapEntryCounter counter = new SourceMapEntryCounter();
+		generator.setSourceRoot(consumer.getSourceRoot());
 		consumer.visitMappings(counter);
 		consumer.visitMappings(new SourceMapConsumerV3.EntryVisitor()
 		{
@@ -778,6 +1003,7 @@
 		}
 		final SourceMapGeneratorV3 generator = new SourceMapGeneratorV3();
 		final SourceMapEntryCounter counter = new SourceMapEntryCounter();
+		generator.setSourceRoot(consumer.getSourceRoot());
 		consumer.visitMappings(counter);
 		consumer.visitMappings(new SourceMapConsumerV3.EntryVisitor()
 		{
@@ -816,6 +1042,7 @@
 		}
 		final SourceMapGeneratorV3 generator = new SourceMapGeneratorV3();
 		final SourceMapEntryCounter counter = new SourceMapEntryCounter();
+		generator.setSourceRoot(consumer.getSourceRoot());
 		consumer.visitMappings(counter);
 		consumer.visitMappings(new SourceMapConsumerV3.EntryVisitor()
 		{
@@ -863,7 +1090,7 @@
 	    fi.constructorLine = -1;
 	    fi.suppressLine = -1;
 	    fi.fileoverviewLine = -1;
-	    fi.googProvideLine = -1;
+		fi.googProvideLine = -1;
 		boolean inInjectHTML = false;
 	    for (int i = 0; i < n; i++)
 	    {
@@ -872,7 +1099,7 @@
 	        int c = line.indexOf("*/");
 	        if (c > -1 && constructorCount > 0 && constructorCount == numProvides)
 	        {
-                return fi;
+                break;
 	        }
 	        else
 	        {
@@ -943,7 +1170,8 @@
 					        				fi.impls = new ArrayList<String>();
 					        			c2 = line.indexOf("}", c);
 					        			String impl = line.substring(c + 13, c2);
-					        			fi.impls.add(impl);
+					        			if (!fi.impls.contains(impl) && !impl.contentEquals(className))
+					        				fi.impls.add(impl);
 					        			if (impl.equals("org.apache.royale.core.ICSSImpl"))
 					        				needCSS = true;
 					        		}
@@ -956,7 +1184,8 @@
 						        				fi.impls = new ArrayList<String>();
 						        			c2 = line.indexOf("}", c);
 						        			String impl = line.substring(c + 10, c2);
-						        			fi.impls.add(impl);
+						        			if (!fi.impls.contains(impl) && !impl.contentEquals(className))
+						        				fi.impls.add(impl);
 						        		}
 						        		else
 						        		{
@@ -974,6 +1203,7 @@
 						    						if (staticDep.equals(className))
 						    							continue;
 						    						staticInitializers.add(staticDep);
+						    						staticInitializerOwners.add(className);
 						    					}
 						    				}
 						    				else
@@ -994,9 +1224,9 @@
 									        			fi.deps = new ArrayList<String>();
 									        			if (line.length() > 2) // don't add blank or space if no deps
 									        				fi.deps.addAll(Arrays.asList(line.split(",")));
-								    					fi.depsLine = i;
+//								    					fi.depsLine = i;
 								    				}
-								    				else if (fi.depsLine == 0)
+								    				else /* if (fi.depsLine == 0) */
 								    				{
 								    					token = JSGoogEmitterTokens.GOOG_REQUIRE.getToken();
 								    					c = line.indexOf(token);
@@ -1020,6 +1250,14 @@
 		        }
 	        }
 	    }
+	    if (fi.deps != null)
+	    {
+	    	Collections.sort(fi.deps);
+	    }
+	    if (fi.staticDeps != null)
+	    {
+	    	Collections.sort(fi.staticDeps);
+	    }
 	    return fi;
 	}
 	
@@ -1080,7 +1318,10 @@
 									        File.separator + assetFileName);
 							        FileUtils.copyFile(assetFile, destFile);
 
-							        System.out.println("Copied assets of the '" + nameOfClass + "' class");
+							        if (verbose)
+									{
+										System.out.println("Copied assets of the '" + nameOfClass + "' class");
+									}
 						        }
 					        }
     				    }
@@ -1092,21 +1333,9 @@
     		}
         }
 
-		String fwdClassPath = className.replace(".", "/");
-		String bckClassPath = className.replace(".", "\\");
         for (ISWC swc : swcs)
         {
-        	ISWCFileEntry fileEntry =  swc.getFile("js/src/" + fwdClassPath + ".js");
-        	if (fileEntry == null)
-        		fileEntry = swc.getFile("js/out/" + fwdClassPath + ".js");
-        	if (fileEntry == null)
-        		fileEntry = swc.getFile("js/src/" + bckClassPath + ".js");
-        	if (fileEntry == null)
-        		fileEntry = swc.getFile("js/out/" + bckClassPath + ".js");
-            if (fileEntry == null)
-                fileEntry = swc.getFile("js\\src\\" + bckClassPath + ".js");
-            if (fileEntry == null)
-                fileEntry = swc.getFile("js\\out\\" + bckClassPath + ".js");
+			ISWCFileEntry fileEntry = getFileEntry(swc, className);
     		if (fileEntry != null)
     		{
     			fn = outputFolderPath + File.separator + classPath + ".js";
@@ -1123,7 +1352,28 @@
     				}
     				outStream.flush();
     				outStream.close();    					
-    				inStream.close();
+					inStream.close();
+					
+					//if source maps requested, copy from the swc, if available
+					if (sourceMaps)
+					{
+						ISWCFileEntry sourceMapFileEntry = getFileEntry(swc, className, ".js.map");
+						if (sourceMapFileEntry != null)
+						{
+							String sourceMapFn = outputFolderPath + File.separator + classPath + ".js.map";
+							File sourceMapDestFile = new File(sourceMapFn);
+							inStream = sourceMapFileEntry.createInputStream();
+							outStream = FileUtils.openOutputStream(sourceMapDestFile);
+							b = new byte[1024 * 1024];
+							while ((bytes_read = inStream.read(b)) != -1)
+							{
+								outStream.write(b, 0, bytes_read);
+							}
+							outStream.flush();
+							outStream.close();    					
+							inStream.close();
+						}
+					}
 
     				// (erikdebruin) copy class assets files
     				if (className.contains("org.apache.royale"))
@@ -1150,7 +1400,10 @@
     		    				inStream.close();
     		    				outStream.flush();
     		    				outStream.close();
-						        System.out.println("Copied asset " + assetName);
+						        if (verbose)
+								{
+									System.out.println("Copied asset " + assetName);
+								}
     						}
     					}
     				}
@@ -1165,6 +1418,29 @@
 		problems.add(new FileNotFoundProblem(className));
 		return "";
 	}
+
+	private ISWCFileEntry getFileEntry(ISWC swc, String className)
+	{
+		return getFileEntry(swc, className, ".js");
+	}
+
+	private ISWCFileEntry getFileEntry(ISWC swc, String className, String extension)
+	{
+		String fwdClassPath = className.replace(".", "/");
+		String bckClassPath = className.replace(".", "\\");
+		ISWCFileEntry fileEntry = swc.getFile("js/src/" + fwdClassPath + extension);
+		if (fileEntry == null)
+			fileEntry = swc.getFile("js/out/" + fwdClassPath + extension);
+		if (fileEntry == null)
+			fileEntry = swc.getFile("js/src/" + bckClassPath + extension);
+		if (fileEntry == null)
+			fileEntry = swc.getFile("js/out/" + bckClassPath + extension);
+		if (fileEntry == null)
+			fileEntry = swc.getFile("js\\src\\" + bckClassPath + extension);
+		if (fileEntry == null)
+			fileEntry = swc.getFile("js\\out\\" + bckClassPath + extension);
+		return fileEntry;
+	}
 	
 	/*
 	private ArrayList<String> getDirectDependencies(String fn)
@@ -1225,18 +1501,20 @@
 	{		
 	}
 	
-	private String getDependencies(ArrayList<String> deps)
+	private void appendDependencies(ArrayList<String> deps, StringBuilder builder)
 	{
-		String s = "";
+		boolean hasDeps = false;
 		for (String dep : deps)
 		{
-			if (s.length() > 0)
+			if (hasDeps)
 			{
-				s += ", ";
+				builder.append(", ");
 			}
-			s += "'" + dep + "'";			
+			builder.append("'");
+			builder.append(dep);
+			builder.append("'");
+			hasDeps = true;
 		}
-		return s;
 	}
 
 	String relativePath(String path)
@@ -1268,6 +1546,11 @@
 		return path;
 	}
 	
+	boolean isGoogProvided(String className)
+	{
+		return ((RoyaleJSProject)project).isGoogProvided(className);
+	}
+	
 	boolean isExternal(String className)
 	{
 		ICompilationUnit cu = project.resolveQNameToCompilationUnit(className);
@@ -1292,7 +1575,7 @@
 		public ArrayList<String> staticDeps;
 		public ArrayList<String> provides;
 		public int constructorLine;
-		public int depsLine;
+//		public int depsLine;
 		public int suppressLine;
 		public int fileoverviewLine;
 		public int googProvideLine;
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleJSProject.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleJSProject.java
index 2c2b52c..8bf9044 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleJSProject.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleJSProject.java
@@ -18,6 +18,7 @@
  */
 package org.apache.royale.compiler.internal.projects;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -32,12 +33,14 @@
 import org.apache.royale.compiler.asdoc.royale.ASDocComment;
 import org.apache.royale.compiler.clients.JSConfiguration;
 import org.apache.royale.compiler.common.DependencyType;
+import org.apache.royale.compiler.common.DependencyTypeSet;
 import org.apache.royale.compiler.config.CompilerDiagnosticsConstants;
 import org.apache.royale.compiler.config.Configuration;
 import org.apache.royale.compiler.config.Configurator;
 import org.apache.royale.compiler.css.ICSSMediaQueryCondition;
 import org.apache.royale.compiler.css.ICSSRule;
 import org.apache.royale.compiler.definitions.IDefinition;
+import org.apache.royale.compiler.definitions.IFunctionDefinition;
 import org.apache.royale.compiler.definitions.ITypeDefinition;
 import org.apache.royale.compiler.definitions.metadata.IMetaTag;
 import org.apache.royale.compiler.definitions.metadata.IMetaTagAttribute;
@@ -58,14 +61,15 @@
 import org.apache.royale.compiler.internal.tree.mxml.MXMLFileNode;
 import org.apache.royale.compiler.internal.units.SWCCompilationUnit;
 import org.apache.royale.compiler.internal.workspaces.Workspace;
-import org.apache.royale.compiler.mxml.IMXMLTypeConstants;
 import org.apache.royale.compiler.targets.ITargetSettings;
 import org.apache.royale.compiler.tree.as.IASNode;
 import org.apache.royale.compiler.tree.as.IClassNode;
 import org.apache.royale.compiler.tree.as.IDefinitionNode;
+import org.apache.royale.compiler.tree.as.IDocumentableDefinitionNode;
 import org.apache.royale.compiler.tree.as.IInterfaceNode;
 import org.apache.royale.compiler.units.ICompilationUnit;
 import org.apache.royale.compiler.units.ICompilationUnit.UnitType;
+import org.apache.royale.swc.ISWC;
 
 import com.google.common.collect.ImmutableList;
 
@@ -100,6 +104,24 @@
     public ICompilationUnit mainCU;
 
     @Override
+    public void addDependency(ICompilationUnit from, ICompilationUnit to, DependencyTypeSet dt, String qname)
+    {
+        if (to.getCompilationUnitType() == UnitType.SWC_UNIT)
+        {
+            List<IDefinition> dp = to.getDefinitionPromises();
+            if(dp.size() > 0)
+            {
+                if (!isGoogProvided(dp.get(0).getQualifiedName()))
+                {
+                    SWCCompilationUnit swcUnit = (SWCCompilationUnit) to;
+                    swcExterns.add(swcUnit.getSWC());
+                }
+            }
+        }
+        super.addDependency(from, to, dt, qname);
+    }
+
+    @Override
     public void addDependency(ICompilationUnit from, ICompilationUnit to,
                               DependencyType dt, String qname)
     {
@@ -110,24 +132,34 @@
 
         IDefinition def = dp.get(0);
         IDefinition actualDef = ((DefinitionPromise) def).getActualDefinition();
-        IDefinitionNode defNode = actualDef != null ? actualDef.getNode() : null;
-        if (to.getCompilationUnitType() == UnitType.AS_UNIT && (defNode instanceof IClassNode || defNode instanceof IInterfaceNode))
+        if (to.getCompilationUnitType() == UnitType.AS_UNIT)
         {
-        	String defname = def.getQualifiedName();
-	        IASDocComment asDoc = (defNode instanceof IClassNode) ? 
-	        						(IASDocComment) ((IClassNode)defNode).getASDocComment() :
-	        						(IASDocComment) ((IInterfaceNode)defNode).getASDocComment();
-	        if (asDoc != null && (asDoc instanceof ASDocComment))
-	        {
-	            String asDocString = ((ASDocComment)asDoc).commentNoEnd();
-	            if (asDocString.contains(JSRoyaleEmitterTokens.EXTERNS.getToken()))
-	            {
-	            	if (!sourceExterns.contains(defname))
-	            		sourceExterns.add(defname);
-	            }
-	        }
+            IDefinitionNode defNode = actualDef != null ? actualDef.getNode() : null;
+        	if (defNode instanceof IClassNode || defNode instanceof IInterfaceNode)
+        	{
+	        	String defname = def.getQualifiedName();
+		        IASDocComment asDoc = (defNode instanceof IClassNode) ?
+		        						(IASDocComment) ((IClassNode)defNode).getASDocComment() :
+		        						(IASDocComment) ((IInterfaceNode)defNode).getASDocComment();
+		        if (asDoc != null && (asDoc instanceof ASDocComment))
+		        {
+		            String asDocString = ((ASDocComment)asDoc).commentNoEnd();
+		            if (asDocString.contains(JSRoyaleEmitterTokens.EXTERNS.getToken()))
+		            {
+		            	if (!sourceExterns.contains(defname))
+		            		sourceExterns.add(defname);
+		            }
+		        }
+        	}
         }
-        // IDefinition def = to.getDefinitionPromises().get(0);
+        if (to.getCompilationUnitType() == UnitType.SWC_UNIT)
+        {
+            if (!isGoogProvided(def.getQualifiedName()))
+            {
+                SWCCompilationUnit swcUnit = (SWCCompilationUnit) to;
+                swcExterns.add(swcUnit.getSWC());
+            }
+        }
         boolean isInterface = (actualDef instanceof InterfaceDefinition) && (dt == DependencyType.INHERITANCE);
         if (!isInterface)
         {
@@ -160,7 +192,7 @@
         super.addDependency(from, to, dt, qname);
     }
     
-    private synchronized void updateRequiresMap(ICompilationUnit from, ICompilationUnit to, 
+    private synchronized void updateRequiresMap(ICompilationUnit from, ICompilationUnit to,
     																		DependencyType dt, String qname)
     {
         HashMap<String, DependencyType> reqs;
@@ -176,19 +208,23 @@
             // inheritance is important so remember it
             if (reqs.get(qname) != DependencyType.INHERITANCE)
             {
-                if (!isExternalLinkage(to))
+                if (isGoogProvided(qname))
+                {
                     reqs.put(qname, dt);
+                }
             }
         }
-        else if (!isExternalLinkage(to) || qname.equals("Namespace"))
+        else if (isGoogProvided(qname) || qname.equals("Namespace"))
         {
             if (qname.equals("XML"))
+            {
                 needXML = true;
+            }
             reqs.put(qname, dt);
-        }    	
+        }
     }
 
-    private synchronized void updateJSModulesMap(ICompilationUnit from, ICompilationUnit to, 
+    private synchronized void updateJSModulesMap(ICompilationUnit from, ICompilationUnit to,
 			DependencyType dt, String qname)
     {
         HashMap<String, DependencyType> reqs;
@@ -216,7 +252,7 @@
         }
     }
     
-    private synchronized void updateInterfacesMap(ICompilationUnit from, ICompilationUnit to, 
+    private synchronized void updateInterfacesMap(ICompilationUnit from, ICompilationUnit to,
 			DependencyType dt, String qname)
     {
         HashMap<String, String> interfacesArr;
@@ -232,10 +268,13 @@
 
         if (!interfacesArr.containsKey(qname))
         {
-            if (!isExternalLinkage(to))
-            	interfacesArr.put(qname, qname);
+            if (isGoogProvided(qname))
+            {
+                interfacesArr.put(qname, qname);
+            }
         }
     }
+
     public boolean needLanguage;
     public boolean needCSS;
     public boolean needXML;
@@ -245,6 +284,9 @@
 
     // definitions that had @externs in the source
     public ArrayList<String> sourceExterns = new ArrayList<String>();
+
+    // swcs that contain referenced externs
+    public Set<ISWC> swcExterns = new HashSet<ISWC>();
     
     // definitions that should be considered external linkage
     public Collection<String> unitTestExterns;
@@ -270,6 +312,65 @@
         return null;
     }
 
+    public boolean isExterns(String qname)
+    {
+		ICompilationUnit cu = resolveQNameToCompilationUnit(qname);
+        if (cu == null)
+        {
+            return false;
+        }
+        if (cu.getCompilationUnitType().equals(ICompilationUnit.UnitType.SWC_UNIT))
+        {
+            return !isGoogProvided(qname);
+        }
+        else if (!cu.getCompilationUnitType().equals(ICompilationUnit.UnitType.AS_UNIT))
+        {
+            return false;
+        }
+
+        IDefinition def = resolveQNameToDefinition(qname);
+        if (def == null)
+        {
+            return false;
+        }
+
+        IDefinitionNode node = def.getNode();
+        if (!(node instanceof IDocumentableDefinitionNode))
+        {
+            return false;
+        }
+
+        IDocumentableDefinitionNode docNode = (IDocumentableDefinitionNode) node;
+        IASDocComment comment = docNode.getASDocComment();
+        if (!(comment instanceof ASDocComment))
+        {
+            return false;
+        }
+        ASDocComment royaleComment = (ASDocComment) comment;
+        return royaleComment.commentNoEnd().contains(JSRoyaleEmitterTokens.EXTERNS.getToken());
+    }
+
+    public boolean isGoogProvided(String qname)
+    {
+		ICompilationUnit cu = resolveQNameToCompilationUnit(qname);
+        if (cu == null)
+        {
+            //TODO: maybe this this should be false because we can't actually
+            //check whether it's a goog.provide() object or not
+            return true;
+        }
+        
+        if (cu.getCompilationUnitType().equals(ICompilationUnit.UnitType.SWC_UNIT))
+        {
+            SWCCompilationUnit swcUnit = (SWCCompilationUnit) cu;
+            ISWC swc = swcUnit.getSWC();
+            String qnameFilePath = "js/out/" + qname.replace('.', '/') + ".js";
+            return swc.getFile(qnameFilePath) != null;
+        }
+
+        return !isExterns(qname);
+    }
+
     public boolean isExternalLinkage(ICompilationUnit cu)
     {
         if (linkageChecker == null)
@@ -298,7 +399,11 @@
         try {
             qnames = cu.getQualifiedNames();
             String qname = qnames.get(0);
-            if (qname.equals("QName") || qname.equals("XML") || qname.equals("XMLList"))
+            // if compiling against airglobal/playerglobal, we have to keep QName, XML, XMLList from being seens
+            // as external otherwise theJS implementations won't get added to the output.  But if the definitions
+            // come from XML.SWC assume the linkage is right in case these files get excluded from modules
+            if ((cu.getAbsoluteFilename().contains("airglobal") || cu.getAbsoluteFilename().contains("playerglobal")) &&
+            		(qname.equals("QName") || qname.equals("XML") || qname.equals("XMLList")))
                 return false;
         } catch (InterruptedException e1) {
             // TODO Auto-generated catch block
@@ -523,6 +628,15 @@
         }
         return false;
 	}
+    
+    @Override
+    public boolean isParameterCountMismatchAllowed(IFunctionDefinition func,
+                                                   int formalCount, int actualCount) {
+        if ((func.getBaseName().equals("int") || func.getBaseName().equals("uint")) && func.isConstructor()) {
+            if (actualCount == 1) return true;
+        }
+        return super.isParameterCountMismatchAllowed(func, formalCount, actualCount);
+    }
 	
     /**
      * List of compiler defines so it can be overridden
@@ -534,4 +648,23 @@
         return list;
     }
 
+
+	@Override
+	public File getLinkReport(Configuration config) {
+		File f = config.getLinkReport();
+		if (f != null)
+		{
+			String baseName = f.getName();
+			String suffix = "";
+			int c = baseName.indexOf(".");
+			if (c != -1)
+			{
+				suffix = baseName.substring(c);
+				baseName = baseName.substring(0, c);
+			}
+			baseName += "-js" + suffix;
+			f = new File(f.getParentFile(), baseName);
+		}
+		return f;
+	}
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/targets/JSTarget.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/targets/JSTarget.java
index 1297aa1..2525bd8 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/targets/JSTarget.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/targets/JSTarget.java
@@ -149,7 +149,7 @@
             //                }
             //            }
             //
-            //            createLinkReport(problems);
+            createLinkReport(problems);
 
             return application;
         }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/targets/RoyaleJSTarget.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/targets/RoyaleJSTarget.java
index 22cddfd..0fea71d 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/targets/RoyaleJSTarget.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/targets/RoyaleJSTarget.java
@@ -28,11 +28,13 @@
 import java.util.Set;
 import java.util.TreeSet;
 
+import org.apache.royale.compiler.common.DependencyType;
 import org.apache.royale.compiler.css.ICSSDocument;
 import org.apache.royale.compiler.css.ICSSManager;
 import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.internal.css.semantics.ActivatedStyleSheets;
 import org.apache.royale.compiler.internal.driver.js.royale.JSCSSCompilationSession;
+import org.apache.royale.compiler.internal.projects.DependencyGraph;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
 import org.apache.royale.compiler.internal.units.SWCCompilationUnit;
 import org.apache.royale.compiler.problems.FileNotFoundProblem;
@@ -147,7 +149,6 @@
     {
         JSCSSCompilationSession cssCompilationSession = (JSCSSCompilationSession) royaleProject.getCSSCompilationSession();
         cssCompilationSession.setKeepAllTypeSelectors(targetSettings.keepAllTypeSelectors());
-        cssCompilationSession.setExcludeDefaultsCSSFiles(targetSettings.getExcludeDefaultsCSSFiles());
         
         // Performance heuristic: let's start compilation on all of the compilation
         // units we know about up front. This is particularly useful on SWC projects where 
@@ -234,6 +235,14 @@
 
             // If there's more dependencies introduced by CSS, the loop continues.
             done = !allCompilationUnitsInTarget.addAll(cssDependencies);
+            if (done)
+            {
+	            DependencyGraph graph = royaleProject.getDependencyGraph();
+	            for (ICompilationUnit cu : cssDependencies)
+	            {
+	            	graph.addDependency(mainCU, cu, DependencyType.EXPRESSION);
+	            }
+            }
         }
 
         // add to front so user specified css overrides defaults
@@ -302,7 +311,9 @@
                 final File swcFile = new File(compilationUnit.getAbsoluteFilename());
                 final ICSSDocument defaultCSS = cssManager.getDefaultCSS(swcFile);
                 if (defaultCSS != null)
+                {
                     result.put(defaultCSS, swcFile);
+                }
             }
         }
         return result;
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/utils/JSClosureCompilerWrapper.java b/compiler-jx/src/main/java/org/apache/royale/compiler/utils/JSClosureCompilerWrapper.java
index 2207985..ae3d614 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/utils/JSClosureCompilerWrapper.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/utils/JSClosureCompilerWrapper.java
@@ -19,19 +19,13 @@
 
 package org.apache.royale.compiler.utils;
 
-import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileWriter;
 import java.io.IOException;
-import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import java.util.logging.Level;
 
 import com.google.javascript.jscomp.CheckLevel;
@@ -42,9 +36,11 @@
 import com.google.javascript.jscomp.CompilerOptions;
 import com.google.javascript.jscomp.CompilerOptions.LanguageMode;
 import com.google.javascript.jscomp.DependencyOptions;
+import com.google.javascript.jscomp.DependencyOptions.DependencyMode;
 import com.google.javascript.jscomp.DiagnosticGroups;
+import com.google.javascript.jscomp.Result;
+import com.google.javascript.jscomp.RoyaleClosurePassConfig;
 import com.google.javascript.jscomp.RoyaleDiagnosticGroups;
-import com.google.javascript.jscomp.ModuleIdentifier;
 import com.google.javascript.jscomp.ShowByPathWarningsGuard;
 import com.google.javascript.jscomp.SourceFile;
 import com.google.javascript.jscomp.SourceMap;
@@ -54,11 +50,14 @@
 public class JSClosureCompilerWrapper
 {
 
-    public JSClosureCompilerWrapper(List<String> args)
+    public JSClosureCompilerWrapper(List<String> args) throws IOException
     {
         Compiler.setLoggingLevel(Level.INFO);
 
         compiler_ = new Compiler();
+        jsSourceFiles_ = new ArrayList<SourceFile>();
+        jsExternsFiles_ = new ArrayList<SourceFile>();
+        
         filterOptions(args);
         
         ArrayList<String> splitArgs = new ArrayList<String>();
@@ -76,9 +75,6 @@
 		splitArgs.toArray(stringArgs);
         options_ = new CompilerOptionsParser(stringArgs).getOptions();
         
-        jsSourceFiles_ = new ArrayList<SourceFile>();
-        jsExternsFiles_ = new ArrayList<SourceFile>();
-        
         initOptions(args);
         initExterns();
 
@@ -93,8 +89,8 @@
     private String variableMapInputPath;
     private String propertyMapInputPath;
     private boolean skipTypeInference;
-    private Set<String> provideds;
     private boolean sourceMap = false;
+    private boolean verbose = false;
     
     public String targetFilePath;
     
@@ -118,22 +114,25 @@
         jsSourceFiles_.add(file);
     }
 
-    public void setProvideds(Set<String> set)
-    {
-    	provideds = set;
-    }
-
     public void setSourceMap(boolean enabled)
     {
         sourceMap = enabled;
     }
-    
-    public void compile()
+
+    public void setVerbose(boolean enabled)
     {
-    	System.out.println("list of source files");
-    	for (SourceFile file : jsSourceFiles_)
-    		System.out.println(file.getName());
-    	System.out.println("end of list of source files");
+        verbose = enabled;
+    }
+    
+    public boolean compile()
+    {
+        if (verbose)
+        {
+            System.out.println("list of source files");
+            for (SourceFile file : jsSourceFiles_)
+                System.out.println(file.getName());
+            System.out.println("end of list of source files");
+        }
     	File outputFolder = new File(targetFilePath).getParentFile();
         if (variableMapInputPath != null)
         {
@@ -141,8 +140,6 @@
         	try {
             	VariableMap map = VariableMap.load(inputFile.getAbsolutePath());
 				CompilerMapFetcher.setVariableMap(options_, map);
-				Set<String> usedVars = getUsedVars(inputFile);
-				compiler_.addExportedNames(usedVars);
 			} catch (IOException e) {
 				// TODO Auto-generated catch block
 				e.printStackTrace();
@@ -161,9 +158,11 @@
 			}
         }
 
-
-        compiler_.compile(jsExternsFiles_, jsSourceFiles_, options_);
-
+        compiler_.setPassConfig(new RoyaleClosurePassConfig(options_, 
+        		jsSourceFiles_.get(jsSourceFiles_.size() - 1).getName(), 
+        		variableMapInputPath == null ? null : new File(outputFolder, variableMapInputPath)));
+        Result result = compiler_.compile(jsExternsFiles_, jsSourceFiles_, options_);
+        
         try
         {
             FileWriter targetFile = new FileWriter(targetFilePath);
@@ -223,65 +222,8 @@
             System.err.println("Error message: " + message.toString());
         }
         */
-    }
-    
-    private Set<String> getUsedVars(File file)
-    {
-    	HashMap<String, String> vars = new HashMap<String, String>();
-    	
-        try
-        {
-            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF8"));
-
-            String line = in.readLine();
-
-            while (line != null)
-            {
-                int c = line.indexOf(":");
-                if (c != -1)
-                {
-                	String name = line.substring(0, c);
-                	
-                	String var = line.substring(c + 1).trim();
-                	vars.put(name, var);
-                }
-                line = in.readLine();
-            }
-            
-            // remove all vars that are used by this module
-            // that way they will re-use the names in the
-            // loader
-            for (String name : provideds)
-            {
-            	name = name.replace('.', '$');
-            	Set<String> keys = vars.keySet();
-            	ArrayList<String> remKeys = new ArrayList<String>();
-            	for (String key : keys)
-            	{
-            		if (key.contains(name))
-            		{
-            			remKeys.add(key);
-            		}
-            	}
-            	for (String key : remKeys)
-            	{
-            		vars.remove(key);
-            	}
-            }
-            in.close();
-        }
-        catch (Exception e)
-        {
-            // nothing to see, move along...
-        }
-        HashSet<String> usedVars = new HashSet<String>();
-    	Set<String> keys = vars.keySet();
-    	for (String key : keys)
-    	{
-    		usedVars.add(vars.get(key));
-    	}
-        return usedVars;
-    }
+        return result.success;
+    }    
     
     @SuppressWarnings( "deprecation" )
     private void initExterns()
@@ -307,11 +249,13 @@
 		final String VARIABLE_MAP = "--variable_map_output_file ";
 		final String PROPERTY_INPUT_MAP = "--property_map_input_file ";
 		final String VARIABLE_INPUT_MAP = "--variable_map_input_file ";
+		final String EXTERNS = "--externs ";
 		String propEntry = null;
 		String varEntry = null;
 		String skipEntry = null;
 		String propInputEntry = null;
 		String varInputEntry = null;
+		ArrayList<String> removeArgs = new ArrayList<String>();
 
     	for (String s : args)
     	{
@@ -344,6 +288,13 @@
     			skipEntry = s;
     			skipTypeInference = true;
     		}
+    		
+    		if (s.startsWith(EXTERNS))
+    		{
+    			String fileName = s.substring(EXTERNS.length());
+    			addJSExternsFile(fileName);
+    			removeArgs.add(s);
+    		}    			
     	}
     	if (varEntry != null)
     		args.remove(varEntry);
@@ -355,6 +306,10 @@
     		args.remove(propInputEntry);
     	if (skipEntry != null)
     		args.remove(skipEntry);
+    	for (String s : removeArgs)
+    	{
+    		args.remove(s);
+    	}
     		
     }
     
@@ -407,14 +362,17 @@
     		WarningLevel.VERBOSE.setOptionsForWarningLevel(options_);
         
         String[] asdocTags = new String[] {"productversion", 
-        		"playerversion", "langversion", "copy", 
-        		"asparam", "asreturn", "asprivate",
+        		"playerversion", "langversion", "copy", "span", "para", "throw", "tiptext",
+        		"asparam", "asreturn", "asreturns", "asprivate",
         		"royaleignoreimport", "royaleignorecoercion", "royaleemitcoercion",
+                "royalesuppresscompleximplicitcoercion","royalesuppressresolveuncertain",
+                "royalesuppressvectorindexcheck","royalesuppressexport", "royalesuppressclosure",
                 "royalenoimplicitstringconversion","royaledebug"};
         options_.setExtraAnnotationNames(Arrays.asList(asdocTags));
     }
     
-    public void setOptions(String sourceMapPath, boolean useStrictPublishing, boolean manageDependencies, String projectName)
+    @SuppressWarnings("deprecation")
+	public void setOptions(String sourceMapPath, boolean useStrictPublishing, boolean manageDependencies, String projectName)
     {
         if (useStrictPublishing)
         {
@@ -432,10 +390,10 @@
             options_.setDeadAssignmentElimination(true);
             options_.setInlineConstantVars(true);
             options_.setInlineFunctions(true);
-            options_.setInlineLocalFunctions(true);
-            options_.setCrossModuleCodeMotion(true);
+            options_.setInlineLocalVariables(true);
+            options_.setCrossChunkCodeMotion(true);
             options_.setCoalesceVariableNames(true);
-            options_.setCrossModuleMethodMotion(true);
+            options_.setCrossChunkMethodMotion(true);
             options_.setInlineProperties(true);
             options_.setInlineVariables(true);
             options_.setSmartNameRemoval(true);
@@ -450,8 +408,6 @@
             options_.setAliasAllStrings(true);
             options_.setConvertToDottedProperties(true);
             options_.setRewriteFunctionExpressions(true);
-            options_.setOptimizeParameters(true);
-            options_.setOptimizeReturns(true);
             options_.setOptimizeCalls(true);
             options_.setOptimizeArgumentsArray(true);
             options_.setGenerateExports(true);
@@ -460,14 +416,11 @@
                     new String[] { "goog/", "externs/svg.js" },
                     ShowByPathWarningsGuard.ShowType.EXCLUDE));
             
-            DependencyOptions dopts = new DependencyOptions();
-            ArrayList<ModuleIdentifier> entryPoints = new ArrayList<ModuleIdentifier>();
-            entryPoints.add(ModuleIdentifier.forClosure(projectName));
-            dopts.setDependencyPruning(manageDependencies)
-                 .setDependencySorting(manageDependencies)
-                 .setMoocherDropping(manageDependencies)
-                 .setEntryPoints(entryPoints);
-            options_.setDependencyOptions(dopts);
+            ArrayList<String> entryPoints = new ArrayList<String>();
+            if (manageDependencies)
+            	entryPoints.add(projectName);
+            options_.setDependencyOptions(DependencyOptions.fromFlags(manageDependencies ? DependencyMode.PRUNE_LEGACY : DependencyMode.NONE, 
+            				entryPoints, new ArrayList<String>(), null, manageDependencies, false));
             
             // warnings already activated in previous incarnation
             options_.setWarningLevel(DiagnosticGroups.ACCESS_CONTROLS, CheckLevel.WARNING);
@@ -537,14 +490,16 @@
 
     private static class CompilerOptionsParser extends CommandLineRunner
     {
-    	public CompilerOptionsParser(String[] args)
-    	{
-    		super(args);
-    	}
-    	
-    	public CompilerOptions getOptions()
-    	{
-    		return createOptions();
-    	}
+        public CompilerOptionsParser(String[] args)
+        {
+            super(args);
+        }
+        
+        public CompilerOptions getOptions() throws IOException
+        {
+            CompilerOptions options = createOptions();
+            setRunOptions(options);
+            return options;
+        }
     }
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/utils/NativeUtils.java b/compiler-jx/src/main/java/org/apache/royale/compiler/utils/NativeUtils.java
index 0653542..8ff320a 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/utils/NativeUtils.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/utils/NativeUtils.java
@@ -122,8 +122,8 @@
         unescape("unescape"),
         window("window"),
 
-        // (erikdebruin) These aren't strictly 'native' to JS, but the 
-        //               Publisher provides global functions, so, for all 
+        // (erikdebruin) These aren't strictly 'native' to JS, but the
+        //               Publisher provides global functions, so, for all
         //               intends and purposes they behave like they are.
         _int("int"),
         trace("trace"),
@@ -154,6 +154,26 @@
         }
     }
     
+    public enum SyntheticJSType
+    {
+        _int("int"),
+        uint("uint"),
+        Vector("Vector"),
+        Class("Class");
+        
+        private final String value;
+    
+        SyntheticJSType(String value)
+        {
+            this.value = value;
+        }
+    
+        public String getValue()
+        {
+            return value;
+        }
+    }
+    
     public static boolean isNative(String type)
     {
         for (NativeASType test : NativeASType.values())
@@ -175,5 +195,24 @@
         }
         return false;
     }
+    
+    public static boolean isSyntheticJSType(String type)
+    {
+        for (SyntheticJSType test : SyntheticJSType.values())
+        {
+            if (test.getValue().equals(type)) {
+                return true;
+            }
+        }
+        if (type.startsWith("Vector.<")) {
+            return true;
+        }
+        return false;
+    }
+    
+    public static boolean isVector(String type)
+    {
+        return type != null && type.startsWith("Vector.<");
+    }
 
 }
diff --git a/compiler-jx/src/main/resources/downloads.xml b/compiler-jx/src/main/resources/downloads.xml
index ac44d0a..1a4a382 100644
--- a/compiler-jx/src/main/resources/downloads.xml
+++ b/compiler-jx/src/main/resources/downloads.xml
@@ -88,17 +88,17 @@
     <get src="https://raw.githubusercontent.com/kohsuke/args4j/master/LICENSE" dest="${lib.dir}/args4j-LICENSE.txt" ignoreerrors="true"/>
 
     <!--  closure -->
-    <property name="closure.version" value="20170626"/>
+    <property name="closure.version" value="20181210"/>
     <property name="closure.name" value="closure-compiler-v${closure.version}"/>
     <property name="closure.dest.name" value="compiler"/>
     <property name="closure.dest.folder" value="google/closure-compiler"/>
     <property name="closure.dest.filename" value="${closure.dest.name}.jar"/>
     <antcall target="download-dependency-closure">
       <param name="name" value="${closure.name}"/>
-      <param name="src.server" value="http://dl.google.com"/>
+      <param name="src.server" value="https://dl.google.com"/>
       <param name="src.folder" value="closure-compiler"/>
       <param name="src.filename" value="compiler-${closure.version}.zip"/>
-      <param name="src.checksum" value="c565b5a1e12aefa5968b42ea83ea6c28"/>
+      <param name="src.checksum" value="c67fdbf6512d1de6bbb84a69ed3d5b87"/>
     </antcall>
     
     <!--  commons-io -->
@@ -116,13 +116,13 @@
 
     <!--  guava -->
     <property name="guava.name" value="guava"/>
-    <property name="guava.version" value="20.0"/>
+    <property name="guava.version" value="25.1-jre"/>
     <antcall target="download-dependency">
       <param name="name" value="${guava.name}"/>
       <param name="src.server" value="${maven.search.url}"/>
       <param name="src.folder" value="com/google/guava/guava/${guava.version}"/>
       <param name="src.filename" value="guava-${guava.version}.jar"/>
-      <param name="src.checksum" value="f32a8a2524620dbecc9f6bf6a20c293f"/>
+      <param name="src.checksum" value="da3838847d109ac435f0d3ed4ae1c794"/>
       <param name="dest.folder" value=""/>
       <param name="dest.filename" value="${guava.name}.jar"/>
     </antcall>
diff --git a/compiler-jx/src/test/build.xml b/compiler-jx/src/test/build.xml
index c484c04..532436e 100644
--- a/compiler-jx/src/test/build.xml
+++ b/compiler-jx/src/test/build.xml
@@ -31,11 +31,33 @@
 	<property name="maxmem" value="512" />
 	
     <property name="compiler" value="${compiler.tests}/../.."/>
+    <property name="compiler-externc" value="${compiler}/../compiler-externc"/>
 
     <target name="download" description="Downloads third-party JARs">
         <ant antfile="${compiler.tests}/downloads.xml" dir="${compiler.tests}"/>
     	<delete dir="${compiler.tests}/in"/>
     </target>
+    
+    <target name="js.swc">
+        <copy file="${compiler-externc}/src/test/config/compile-as-config.xml"
+        todir="${compiler-externc}/target" />
+        <java jar="${compiler}/lib/compc.jar" fork="true"
+            failonerror="true">
+            <arg value="-targets=SWF"/>
+            <arg value="-load-config=${compiler-externc}/target/compile-as-config.xml" />
+            <arg value="-output=${compiler-externc}/target/js.swc" />
+        </java>
+    </target>
+
+    <target name="custom.swc">
+        <copy file="config/compile-js-config.xml"
+        todir="${compiler}/target" />
+        <java jar="${compiler}/lib/compc.jar" fork="true"
+            failonerror="true">
+            <arg value="-load-config=${compiler}/target/compile-js-config.xml" />
+            <arg value="-output=${compiler}/target/custom.swc" />
+        </java>
+    </target>
 
     <target name="compile.unit.tests">
     	<delete dir="${compiler}/target/test-classes"/>
@@ -181,26 +203,9 @@
             </assertions>
         </junit>
     </target>
-    
-    <target name="copyLastSuccessfulBuild" depends="check_asjs, get_asjs" />
-    <target name="check_asjs" >
-        <available file="${env.ASJS_HOME}/frameworks/libs/Network.swc"
-            type="file"
-            property="asjs.ok"
-            value="true" />
-    </target>
-    <target name="get_asjs" unless="asjs.ok" >
-        <get src="http://apacheflexbuild.cloudapp.net:8080/job/royale-asjs/lastSuccessfulBuild/artifact/out/apache-royale-flexjs-0.9.0-bin.zip" dest="${compiler}/target/junit-temp/royale.zip"/>
-        <unzip src="${compiler}/target/junit-temp/royale.zip" dest="${env.ASJS_HOME}">
-            <patternset>
-                <include name="frameworks/libs/*.swc"/>
-            </patternset>
-        </unzip>
-        <delete file="${compiler}/target/junit-temp/royale.zip" />
-    </target>
- 
-    <target name="main" depends="unit.tests, integration.tests"/>
-    <target name="all" depends="unit.tests, integration.tests, typedef.tests, integration.tests.asjs"/>
+     
+    <target name="main" depends="js.swc, custom.swc, unit.tests, integration.tests"/>
+    <target name="all" depends="main, typedef.tests, integration.tests.asjs"/>
 
     <target name="clean">
         <delete dir="${compiler.tests}/bin"/>
diff --git a/compiler-jx/src/test/config/compile-js-config.xml b/compiler-jx/src/test/config/compile-js-config.xml
new file mode 100644
index 0000000..68a3341
--- /dev/null
+++ b/compiler-jx/src/test/config/compile-js-config.xml
@@ -0,0 +1,46 @@
+<!--
+
+  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.
+
+-->
+<royale-config>
+
+    <compiler>
+        <accessible>true</accessible>
+
+		<targets>
+			<target>SWF</target>
+			<target>JSRoyale</target>
+		</targets>
+        
+        <source-path>
+            <path-element>../../compiler/src/test/royale</path-element>
+        </source-path>
+        
+        <external-library-path>
+            <path-element>../../compiler-externc/target/js.swc</path-element>
+        </external-library-path>
+        
+        <warn-no-constructor>false</warn-no-constructor>
+    </compiler>
+
+	<warn-public-vars>false</warn-public-vars>
+    
+    <include-sources>
+        <path-element>../../compiler/src/test/royale</path-element>
+    </include-sources>
+
+</royale-config>
diff --git a/compiler-jx/src/test/downloads.xml b/compiler-jx/src/test/downloads.xml
index b6b334f..310810c 100644
--- a/compiler-jx/src/test/downloads.xml
+++ b/compiler-jx/src/test/downloads.xml
@@ -119,7 +119,7 @@
     <target name="junit-download-jar" depends="junit-jar-check" unless="junit.jar.exists"
             description="Downloads the JUnit jar.">
         <antcall target="download-jar">
-            <param name="srcUrl" value="http://search.maven.org/remotecontent?filepath=junit/junit/4.10"/>
+            <param name="srcUrl" value="https://search.maven.org/remotecontent?filepath=junit/junit/4.10"/>
             <param name="srcJarFile" value="junit-4.10.jar"/>
             <param name="destDir" value="${lib.dir}"/>
             <param name="destJarFile" value="junit-4.10.jar"/>
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/as/TestExpressions.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/as/TestExpressions.java
index 0333265..e516bb9 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/as/TestExpressions.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/as/TestExpressions.java
@@ -25,6 +25,7 @@
 import org.apache.royale.compiler.tree.as.IBinaryOperatorNode;
 import org.apache.royale.compiler.tree.as.IDynamicAccessNode;
 import org.apache.royale.compiler.tree.as.IFunctionCallNode;
+import org.apache.royale.compiler.tree.as.IFunctionNode;
 import org.apache.royale.compiler.tree.as.IIterationFlowNode;
 import org.apache.royale.compiler.tree.as.IMemberAccessExpressionNode;
 import org.apache.royale.compiler.tree.as.INamespaceAccessExpressionNode;
@@ -518,6 +519,22 @@
         asBlockWalker.visitFunctionCall(node);
         assertOut("addListener('foo', function(event:Object):void {\n\tdoit();\n})");
     }
+    
+    @Test
+    public void testVisitLocalNamedFunction()
+    {
+        IFunctionNode node = (IFunctionNode) getLocalFunction("function a() {};");
+        asBlockWalker.visitFunction(node);
+        assertOut("function a() {\n}");
+    }
+    
+    @Test
+    public void testVisitLocalNamedFunctionWithParamsReturn()
+    {
+        IFunctionNode node = (IFunctionNode) getLocalFunction("function a(foo:int, bar:String = 'goo'):int{return -1;};");
+        asBlockWalker.visitFunction(node);
+        assertOut("function a(foo:int, bar:String = 'goo'):int {\n\treturn -1;\n}");
+    }
 
     @Test
     public void testVisitDynamicAccessNode_1()
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogAccessorMembers.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogAccessorMembers.java
index 3fd051d..69ae550 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogAccessorMembers.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogAccessorMembers.java
@@ -98,10 +98,10 @@
     @Test
     public void testSetAccessor_withBody()
     {
-        ISetterNode node = (ISetterNode) getAccessor("function set foo(value:int):void{trace('haai');}");
+        ISetterNode node = (ISetterNode) getAccessor("function set foo(value:int):void{'haai';}");
         asBlockWalker.visitSetter(node);
         assertOut("Object.defineProperty(\n\tRoyaleTest_A.prototype, \n\t'foo', "
-                + "\n\t{set:function(value) {\n\t\tvar self = this;\n\t\ttrace('haai');\n\t}, configurable:true}\n)");
+                + "\n\t{set:function(value) {\n\t\tvar self = this;\n\t\t'haai';\n\t}, configurable:true}\n)");
     }
 
     @Override
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogClass.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogClass.java
index be3bfbd..67c4caa 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogClass.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogClass.java
@@ -19,16 +19,11 @@
 
 package org.apache.royale.compiler.internal.codegen.js.goog;
 
-import java.io.File;
-import java.util.List;
-
 import org.apache.royale.compiler.driver.IBackend;
 import org.apache.royale.compiler.internal.codegen.as.TestClass;
 import org.apache.royale.compiler.internal.driver.js.goog.GoogBackend;
-import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
 import org.apache.royale.compiler.tree.as.IClassNode;
 import org.apache.royale.compiler.tree.as.IFileNode;
-import org.apache.royale.utils.FilenameNormalization;
 import org.junit.Test;
 
 /**
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogEmitter.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogEmitter.java
index 42e58e3..c40adb9 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogEmitter.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogEmitter.java
@@ -19,15 +19,11 @@
 
 package org.apache.royale.compiler.internal.codegen.js.goog;
 
-import java.io.File;
-import java.util.List;
-
 import org.apache.royale.compiler.driver.IBackend;
 import org.apache.royale.compiler.internal.driver.js.goog.GoogBackend;
 import org.apache.royale.compiler.internal.test.ASTestBase;
 import org.apache.royale.compiler.tree.as.IFileNode;
 import org.apache.royale.compiler.tree.as.IFunctionNode;
-import org.apache.royale.utils.FilenameNormalization;
 import org.junit.Test;
 
 /**
@@ -115,7 +111,7 @@
     @Test
     public void testDefaultParameter()
     {
-        IFunctionNode node = getMethodWithPackage("function method1(p1:int, p2:int, p3:int = 3, p4:int = 4):int{return p1 + p2 + p3 + p4;}");
+        IFunctionNode node = getMethodWithPackage("function method1(p1:Number, p2:Number, p3:Number = 3, p4:Number = 4):Number{return p1 + p2 + p3 + p4;}");
         asBlockWalker.visitFunction(node);
         assertOut("/**\n * @param {number} p1\n * @param {number} p2\n * @param {number=} p3\n * @param {number=} p4\n * @return {number}\n */\n"
                 + "foo.bar.RoyaleTest_A.prototype.method1 = function(p1, p2, p3, p4) {\n"
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogExpressions.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogExpressions.java
index d7c2072..a377574 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogExpressions.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogExpressions.java
@@ -150,6 +150,15 @@
         asBlockWalker.visitFunctionCall(node);
         assertOut("addListener('foo', function(event) {\n\tdoit();\n})");
     }
+    
+    @Override
+    @Test
+    public void testVisitLocalNamedFunctionWithParamsReturn()
+    {
+        IFunctionNode node = (IFunctionNode) getLocalFunction("function a(foo:int, bar:String = 'goo'):int{return -1;};");
+        asBlockWalker.visitFunction(node);
+        assertOut("function a(foo, bar) {\n\tbar = typeof bar !== 'undefined' ? bar : 'goo';\n\treturn -1;\n}");
+    }
 
     @Override
     @Test
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogFieldMembers.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogFieldMembers.java
index 9bb864d..a1318d4 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogFieldMembers.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogFieldMembers.java
@@ -97,7 +97,7 @@
     {
         IVariableNode node = getField("protected var foo:Vector.<Foo>;");
         asBlockWalker.visitVariable(node);
-        assertOut("/**\n * @protected\n * @type {Vector.<Foo>}\n */\nRoyaleTest_A.prototype.foo");
+        assertOut("/**\n * @protected\n * @type {Array.<Foo>}\n */\nRoyaleTest_A.prototype.foo");
     }
 
     @Override
@@ -106,7 +106,7 @@
     {
         IVariableNode node = getField("protected var foo:Vector.<Vector.<Vector.<Foo>>>;");
         asBlockWalker.visitVariable(node);
-        assertOut("/**\n * @protected\n * @type {Vector.<Vector.<Vector.<Foo>>>}\n */\nRoyaleTest_A.prototype.foo");
+        assertOut("/**\n * @protected\n * @type {Array.<Array.<Array.<Foo>>>}\n */\nRoyaleTest_A.prototype.foo");
     }
 
     @Override
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogGlobalClasses.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogGlobalClasses.java
index 0bf0f4a..28aab2a 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogGlobalClasses.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogGlobalClasses.java
@@ -271,7 +271,7 @@
     {
         IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>(['Hello', 'World']);");
         asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {Vector.<string>} */ a = new Array(['Hello', 'World'])");
+        assertOut("var /** @type {Array.<string>} */ a = new Array(['Hello', 'World'])");
     }
 
     @Override
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogGlobalFunctions.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogGlobalFunctions.java
index 5b54916..f979f20 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogGlobalFunctions.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogGlobalFunctions.java
@@ -24,6 +24,7 @@
 import org.apache.royale.compiler.internal.driver.js.goog.GoogBackend;
 import org.apache.royale.compiler.tree.as.IFunctionCallNode;
 import org.apache.royale.compiler.tree.as.IVariableNode;
+import org.junit.Ignore;
 import org.junit.Test;
 
 /**
@@ -121,6 +122,8 @@
         assertOut("var /** @type {boolean} */ a = isNaN(NaN)");
     }
 
+    //isXMLName is in E4X, which is not supported by JavaScript
+    @Ignore
     @Override
     @Test
     public void testIsXMLName()
@@ -209,7 +212,7 @@
     {
         IVariableNode node = getVariable("var a:Vector.<String> = Vector.<String>(['Hello', 'World']);");
         asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {Vector.<string>} */ a = Array(['Hello', 'World'])");
+        assertOut("var /** @type {Array.<string>} */ a = Array(['Hello', 'World'])");
     }
 
     @Override
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogStatements.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogStatements.java
index 4247a29..9df4078 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogStatements.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogStatements.java
@@ -25,6 +25,7 @@
 import org.apache.royale.compiler.internal.tree.as.LabeledStatementNode;
 import org.apache.royale.compiler.tree.as.IFileNode;
 import org.apache.royale.compiler.tree.as.IForLoopNode;
+import org.apache.royale.compiler.tree.as.IIfNode;
 import org.apache.royale.compiler.tree.as.ISwitchNode;
 import org.apache.royale.compiler.tree.as.ITryNode;
 import org.apache.royale.compiler.tree.as.IVariableNode;
@@ -310,6 +311,16 @@
         assertOut("goog.provide('RoyaleTest_A');\n\n/**\n * @constructor\n */\nRoyaleTest_A = function() {\n};\n\nRoyaleTest_A.prototype.royaleTest_a = function() {\n\tvar self = this;\n\ttry {\n\t\ta;\n\t} catch (e) {\n\t\tif (a) {\n\t\t\tif (b) {\n\t\t\t\tif (c)\n\t\t\t\t\tb;\n\t\t\t\telse if (f)\n\t\t\t\t\ta;\n\t\t\t\telse\n\t\t\t\t\te;\n\t\t\t}\n\t\t}\n\t} finally {\n\t}\n\tif (d)\n\t\tfor (var /** @type {number} */ i = 0; i < len; i++)\n\t\t\tbreak;\n\tif (a) {\n\t\twith (ab) {\n\t\t\tc();\n\t\t}\n\t\tdo {\n\t\t\ta++;\n\t\t\tdo\n\t\t\t\ta++;\n\t\t\twhile (a > b);\n\t\t} while (c > d);\n\t}\n\tif (b) {\n\t\ttry {\n\t\t\ta;\n\t\t\tthrow new Error('foo');\n\t\t} catch (e) {\n\t\t\tswitch (i) {\n\t\t\t\tcase 1:\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t} finally {\n\t\t\td;\n\t\t\tvar /** @type {Object} */ a = function(foo, bar) {\n\t\t\t\tbar = typeof bar !== 'undefined' ? bar : 'goo';\n\t\t\t\treturn -1;\n\t\t\t};\n\t\t\teee.dd;\n\t\t\teee.dd;\n\t\t\teee.dd;\n\t\t\teee.dd;\n\t\t}\n\t}\n\tfoo : goog.array.forEach(obj, function (i) {\n\t\tbreak foo;\n\t});\n};");
     }
 
+    @Test
+    public void testVisitIf_NoClauses()
+    {
+        IIfNode node = (IIfNode) getNode(
+                "if (a) ;", IIfNode.class);
+        asBlockWalker.visitIf(node);
+        assertOut("if (a)\n{}\n");
+    }
+
+
     @Override
     protected IBackend createBackend()
     {
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestDefaultInitializers.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestDefaultInitializers.java
index 6129bfd..963d2cf 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestDefaultInitializers.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestDefaultInitializers.java
@@ -25,6 +25,7 @@
 import org.apache.royale.compiler.internal.driver.js.royale.RoyaleBackend;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
 import org.apache.royale.compiler.internal.test.ASTestBase;
+import org.apache.royale.compiler.tree.as.IFunctionNode;
 import org.apache.royale.compiler.tree.as.IVariableNode;
 import org.junit.Test;
 
@@ -35,16 +36,20 @@
     {
         backend = createBackend();
         project = new RoyaleJSProject(workspace, backend);
+        super.setUp();
+    }
+    
+    protected void createConfig(boolean defaultInitializers)
+    {
     	JSGoogConfiguration config = new JSGoogConfiguration();
     	try {
-			config.setJsDefaultInitializers(null, true);
+			config.setJsDefaultInitializers(null, defaultInitializers);
 		} catch (ConfigurationException e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
     	project.config = config;
-        super.setUp();
-	}
+    }
 
     protected IBackend createBackend()
     {
@@ -52,121 +57,312 @@
     }
 
     @Test
-    public void testVarDeclaration_withNumberType()
+    public void testVarDeclaration_defaultInitializers_withNumberType()
     {
+        createConfig(true);
+        IFunctionNode node = (IFunctionNode) getNode("var a:Number;",
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n  var /** @type {number} */ a = NaN;\n  //var /** @type {number} */ a = NaN;\n}");
+    }
+
+    @Test
+    public void testVarDeclaration_noDefaultInitializers_withNumberType()
+    {
+        createConfig(false);
         IVariableNode node = (IVariableNode) getNode("var a:Number;",
                 IVariableNode.class);
         asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {number} */ a = NaN");
+        assertOut("var /** @type {number} */ a");
     }
 
     @Test
-    public void testVarDeclaration_withBooleanType()
+    public void testVarDeclaration_defaultInitializers_withBooleanType()
     {
+        createConfig(true);
+        IFunctionNode node = (IFunctionNode) getNode("var a:Boolean;",
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n  var /** @type {boolean} */ a = false;\n  //var /** @type {boolean} */ a = false;\n}");
+    }
+
+    @Test
+    public void testVarDeclaration_noDefaultInitializers_withBooleanType()
+    {
+        createConfig(false);
         IVariableNode node = (IVariableNode) getNode("var a:Boolean;",
                 IVariableNode.class);
         asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {boolean} */ a = false");
+        assertOut("var /** @type {boolean} */ a");
     }
 
     @Test
-    public void testVarDeclaration_withIntType()
+    public void testVarDeclaration_defaultInitializers_withIntType()
     {
-        IVariableNode node = (IVariableNode) getNode("var a:int;",
-                IVariableNode.class);
-        asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {number} */ a = 0");
+        createConfig(true);
+        IFunctionNode node = (IFunctionNode) getNode("var a:int;",
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n  var /** @type {number} */ a = 0;\n  //var /** @type {number} */ a = 0;\n}");
     }
 
     @Test
-    public void testVarDeclaration_withUintType()
+    public void testVarDeclaration_noDefaultInitializers_withIntType()
     {
-        IVariableNode node = (IVariableNode) getNode("var a:uint;",
-                IVariableNode.class);
-        asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {number} */ a = 0");
+        createConfig(false);
+        IFunctionNode node = (IFunctionNode) getNode("var a:int;",
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        //an exception that always has an initializer
+        assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n  var /** @type {number} */ a = 0;\n  //var /** @type {number} */ a = 0;\n}");
     }
 
     @Test
-    public void testVarDeclaration_withStringType()
+    public void testVarDeclaration_defaultInitializers_withUintType()
     {
+        createConfig(true);
+        IFunctionNode node = (IFunctionNode) getNode("var a:uint;",
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n  var /** @type {number} */ a = 0;\n  //var /** @type {number} */ a = 0;\n}");
+    }
+
+    @Test
+    public void testVarDeclaration_noDefaultInitializers_withUintType()
+    {
+        createConfig(false);
+        IFunctionNode node = (IFunctionNode) getNode("var a:uint;",
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        //an exception that always has an initializer
+        assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n  var /** @type {number} */ a = 0;\n  //var /** @type {number} */ a = 0;\n}");
+    }
+
+    @Test
+    public void testVarDeclaration_defaultInitializers_withStringType()
+    {
+        createConfig(true);
+        IFunctionNode node = (IFunctionNode) getNode("var a:String;",
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n  var /** @type {string} */ a = null;\n  //var /** @type {string} */ a = null;\n}");
+    }
+
+    @Test
+    public void testVarDeclaration_noDefaultInitializers_withStringType()
+    {
+        createConfig(false);
         IVariableNode node = (IVariableNode) getNode("var a:String;",
                 IVariableNode.class);
         asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {string} */ a = null");
+        assertOut("var /** @type {string} */ a");
     }
 
     @Test
-    public void testVarDeclaration_withObjectType()
+    public void testVarDeclaration_defaultInitializers_withObjectType()
     {
+        createConfig(true);
+        IFunctionNode node = (IFunctionNode) getNode("var a:Object;",
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n  var /** @type {Object} */ a = null;\n  //var /** @type {Object} */ a = null;\n}");
+    }
+
+    @Test
+    public void testVarDeclaration_noDefaultInitializers_withObjectType()
+    {
+        createConfig(false);
         IVariableNode node = (IVariableNode) getNode("var a:Object;",
                 IVariableNode.class);
         asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {Object} */ a = null");
+        assertOut("var /** @type {Object} */ a");
     }
 
     @Test
-    public void testVarDeclaration_withArrayType()
+    public void testVarDeclaration_defaultInitializers_withArrayType()
     {
+        createConfig(true);
+        IFunctionNode node = (IFunctionNode) getNode("var a:Array;",
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n  var /** @type {Array} */ a = null;\n  //var /** @type {Array} */ a = null;\n}");
+    }
+
+    @Test
+    public void testVarDeclaration_noDefaultInitializers_withArrayType()
+    {
+        createConfig(false);
         IVariableNode node = (IVariableNode) getNode("var a:Array;",
                 IVariableNode.class);
         asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {Array} */ a = null");
+        assertOut("var /** @type {Array} */ a");
     }
 
     @Test
-    public void testFieldDeclaration_withNumberType()
+    public void testVarDeclaration_defaultInitializers_withChainedAndAllInitialized()
     {
+        createConfig(true);
+        IVariableNode node = (IVariableNode) getNode("var a:Number = 0, b:Number = 0, c:Number = 0;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {number} */ a = 0, /** @type {number} */ b = 0, /** @type {number} */ c = 0");
+    }
+
+    @Test
+    public void testVarDeclaration_defaultInitializers_withChainedAndNoneInitialized()
+    {
+        createConfig(true);
+        IFunctionNode node = (IFunctionNode) getNode("var a:Number, b:Number, c:Number;",
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n  var /** @type {number} */ a = NaN;\n  var /** @type {number} */ b = NaN;\n  var /** @type {number} */ c = NaN;\n  //var /** @type {number} */ a = NaN;\n  //var /** @type {number} */ b = NaN;\n  //var /** @type {number} */ c = NaN;\n}");
+    }
+
+    @Test
+    public void testVarDeclaration_defaultInitializers_withChainedAndFirstInitialized()
+    {
+        createConfig(true);
+        IFunctionNode node = (IFunctionNode) getNode("var a:Number = 1, b:Number, c:Number;",
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n  var /** @type {number} */ b = NaN;\n  var /** @type {number} */ c = NaN;\n  var /** @type {number} */ a = 1;\n  //var /** @type {number} */ b = NaN;\n  //var /** @type {number} */ c = NaN;\n}");
+    }
+
+    @Test
+    public void testVarDeclaration_defaultInitializers_withChainedAndLastInitialized()
+    {
+        createConfig(true);
+        IFunctionNode node = (IFunctionNode) getNode("var a:Number, b:Number, c:Number = 1;",
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n  var /** @type {number} */ a = NaN;\n  var /** @type {number} */ b = NaN;\n  //var /** @type {number} */ a = NaN;\n  //var /** @type {number} */ b = NaN;\n  var /** @type {number} */ c = 1;\n}");
+    }
+
+    @Test
+    public void testFieldDeclaration_defaultInitializers_withNumberType()
+    {
+        createConfig(true);
         IVariableNode node = getField("private var foo:Number;");
         asBlockWalker.visitVariable(node);
         assertOut("/**\n * @private\n * @type {number}\n */\nRoyaleTest_A.prototype.foo = NaN");
     }
 
     @Test
-    public void testFieldDeclaration_withBooleanType()
+    public void testFieldDeclaration_noDefaultInitializers_withNumberType()
     {
+        createConfig(false);
+        IVariableNode node = getField("private var foo:Number;");
+        asBlockWalker.visitVariable(node);
+        assertOut("/**\n * @private\n * @type {number}\n */\nRoyaleTest_A.prototype.foo");
+    }
+
+    @Test
+    public void testFieldDeclaration_defaultInitializers_withBooleanType()
+    {
+        createConfig(true);
         IVariableNode node = getField("private var foo:Boolean;");
         asBlockWalker.visitVariable(node);
         assertOut("/**\n * @private\n * @type {boolean}\n */\nRoyaleTest_A.prototype.foo = false");
     }
 
     @Test
-    public void testFieldDeclaration_withIntType()
+    public void testFieldDeclaration_noDefaultInitializers_withBooleanType()
     {
+        createConfig(false);
+        IVariableNode node = getField("private var foo:Boolean;");
+        asBlockWalker.visitVariable(node);
+        assertOut("/**\n * @private\n * @type {boolean}\n */\nRoyaleTest_A.prototype.foo");
+    }
+
+    @Test
+    public void testFieldDeclaration_defaultInitializers_withIntType()
+    {
+        createConfig(true);
         IVariableNode node = getField("private var foo:int;");
         asBlockWalker.visitVariable(node);
         assertOut("/**\n * @private\n * @type {number}\n */\nRoyaleTest_A.prototype.foo = 0");
     }
 
     @Test
-    public void testFieldDeclaration_withUintType()
+    public void testFieldDeclaration_noDefaultInitializers_withIntType()
     {
+        createConfig(false);
+        IVariableNode node = getField("private var foo:int;");
+        asBlockWalker.visitVariable(node);
+        //an exception that always has an initializer
+        assertOut("/**\n * @private\n * @type {number}\n */\nRoyaleTest_A.prototype.foo = 0");
+    }
+
+    @Test
+    public void testFieldDeclaration_defaultInitializers_withUintType()
+    {
+        createConfig(true);
         IVariableNode node = getField("private var foo:uint;");
         asBlockWalker.visitVariable(node);
         assertOut("/**\n * @private\n * @type {number}\n */\nRoyaleTest_A.prototype.foo = 0");
     }
 
     @Test
-    public void testFieldDeclaration_withStringType()
+    public void testFieldDeclaration_noDefaultInitializers_withUintType()
     {
+        createConfig(false);
+        IVariableNode node = getField("private var foo:uint;");
+        asBlockWalker.visitVariable(node);
+        //an exception that always has an initializer
+        assertOut("/**\n * @private\n * @type {number}\n */\nRoyaleTest_A.prototype.foo = 0");
+    }
+
+    @Test
+    public void testFieldDeclaration_defaultInitializers_withStringType()
+    {
+        createConfig(true);
         IVariableNode node = getField("private var foo:String;");
         asBlockWalker.visitVariable(node);
         assertOut("/**\n * @private\n * @type {string}\n */\nRoyaleTest_A.prototype.foo = null");
     }
 
     @Test
-    public void testFieldDeclaration_withObjectType()
+    public void testFieldDeclaration_noDefaultInitializers_withStringType()
     {
+        createConfig(false);
+        IVariableNode node = getField("private var foo:String;");
+        asBlockWalker.visitVariable(node);
+        assertOut("/**\n * @private\n * @type {string}\n */\nRoyaleTest_A.prototype.foo");
+    }
+
+    @Test
+    public void testFieldDeclaration_defaultInitializers_withObjectType()
+    {
+        createConfig(true);
         IVariableNode node = getField("private var foo:Object;");
         asBlockWalker.visitVariable(node);
         assertOut("/**\n * @private\n * @type {Object}\n */\nRoyaleTest_A.prototype.foo = null");
     }
 
     @Test
-    public void testFieldDeclaration_withArrayType()
+    public void testFieldDeclaration_noDefaultInitializers_withObjectType()
     {
+        createConfig(false);
+        IVariableNode node = getField("private var foo:Object;");
+        asBlockWalker.visitVariable(node);
+        assertOut("/**\n * @private\n * @type {Object}\n */\nRoyaleTest_A.prototype.foo");
+    }
+
+    @Test
+    public void testFieldDeclaration_defaultInitializers_withArrayType()
+    {
+        createConfig(true);
         IVariableNode node = getField("private var foo:Array;");
         asBlockWalker.visitVariable(node);
         assertOut("/**\n * @private\n * @type {Array}\n */\nRoyaleTest_A.prototype.foo = null");
     }
+
+    @Test
+    public void testFieldDeclaration_noDefaultInitializers_withArrayType()
+    {
+        createConfig(false);
+        IVariableNode node = getField("private var foo:Array;");
+        asBlockWalker.visitVariable(node);
+        assertOut("/**\n * @private\n * @type {Array}\n */\nRoyaleTest_A.prototype.foo");
+    }
 }
\ No newline at end of file
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleAccessors.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleAccessors.java
index af854af..917f615 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleAccessors.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleAccessors.java
@@ -46,7 +46,7 @@
                 "public function doStuff():void {label = 'hello, bye'; var theLabel:String = label;}; private var _label:String; public function get label():String {return _label}; public function set label(value:String):void {_label = value}; ",
                 IClassNode.class, WRAP_LEVEL_CLASS);
         asBlockWalker.visitClass(node);
-        String expected = "/**\n * @constructor\n */\nRoyaleTest_A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('RoyaleTest_A', RoyaleTest_A);\n\n\n/**\n * @export\n */\nRoyaleTest_A.prototype.doStuff = function() {\n  this.label = 'hello, bye';\n  var /** @type {string} */ theLabel = this.label;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nRoyaleTest_A.prototype._label;\n\n\n" +
+        String expected = "/**\n * @constructor\n */\nRoyaleTest_A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('RoyaleTest_A', RoyaleTest_A);\n\n\n/**\n * @export\n */\nRoyaleTest_A.prototype.doStuff = function() {\n  this.label = 'hello, bye';\n  var /** @type {string} */ theLabel = this.label;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nRoyaleTest_A.prototype._label = null;\n\n\n" +
         		"RoyaleTest_A.prototype.get__label = function() {\n  return this._label;\n};\n\n\n" +
         		"RoyaleTest_A.prototype.set__label = function(value) {\n  this._label = value;\n};\n\n\n" +
         		"Object.defineProperties(RoyaleTest_A.prototype, /** @lends {RoyaleTest_A.prototype} */ {\n/**\n  * @export\n  * @type {string} */\n" +
@@ -61,7 +61,7 @@
                 "public class B { public function B() {}; public function doStuff():void {this.label = label + 'bye'; var theLabel:String = label;}; private var _label:String; public function get label():String {return _label}; public function set label(value:String):void {_label = value};}",
                 IClassNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitClass(node);
-        String expected = "/**\n * @constructor\n */\nB = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('B', B);\n\n\n/**\n * @export\n */\nB.prototype.doStuff = function() {\n  this.label = this.label + 'bye';\n  var /** @type {string} */ theLabel = this.label;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nB.prototype._label;\n\n\n" +
+        String expected = "/**\n * @constructor\n */\nB = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('B', B);\n\n\n/**\n * @export\n */\nB.prototype.doStuff = function() {\n  this.label = this.label + 'bye';\n  var /** @type {string} */ theLabel = this.label;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nB.prototype._label = null;\n\n\n" +
 				"B.prototype.get__label = function() {\n  return this._label;\n};\n\n\n" +
 				"B.prototype.set__label = function(value) {\n  this._label = value;\n};\n\n\n" +
         		"Object.defineProperties(B.prototype, /** @lends {B.prototype} */ {\n/**\n  * @export\n  * @type {string} */\nlabel: {\n" +
@@ -76,7 +76,7 @@
                 "public function doStuff():void {label = label + 'bye'; var theLabel:String = label;}; private var _label:String; public function get label():String {return _label}; public function set label(value:String):void {_label = value}; ",
                 IClassNode.class, WRAP_LEVEL_CLASS);
         asBlockWalker.visitClass(node);
-        String expected = "/**\n * @constructor\n */\nRoyaleTest_A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('RoyaleTest_A', RoyaleTest_A);\n\n\n/**\n * @export\n */\nRoyaleTest_A.prototype.doStuff = function() {\n  this.label = this.label + 'bye';\n  var /** @type {string} */ theLabel = this.label;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nRoyaleTest_A.prototype._label;\n\n\n" +
+        String expected = "/**\n * @constructor\n */\nRoyaleTest_A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('RoyaleTest_A', RoyaleTest_A);\n\n\n/**\n * @export\n */\nRoyaleTest_A.prototype.doStuff = function() {\n  this.label = this.label + 'bye';\n  var /** @type {string} */ theLabel = this.label;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nRoyaleTest_A.prototype._label = null;\n\n\n" +
 				"RoyaleTest_A.prototype.get__label = function() {\n  return this._label;\n};\n\n\n" +
 				"RoyaleTest_A.prototype.set__label = function(value) {\n  this._label = value;\n};\n\n\n" +
 				"Object.defineProperties(RoyaleTest_A.prototype, /** @lends {RoyaleTest_A.prototype} */ {\n/**\n  * @export\n  * @type {string} */\nlabel: {\n" +
@@ -91,7 +91,7 @@
                 "public class B { public function B() {}; public function doStuff():void {label = this.label; var theLabel:String = label;}; private var _label:String; public function get label():String {return _label}; public function set label(value:String):void {_label = value};}",
                 IClassNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitClass(node);
-        String expected = "/**\n * @constructor\n */\nB = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('B', B);\n\n\n/**\n * @export\n */\nB.prototype.doStuff = function() {\n  this.label = this.label;\n  var /** @type {string} */ theLabel = this.label;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nB.prototype._label;\n\n\n" +
+        String expected = "/**\n * @constructor\n */\nB = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('B', B);\n\n\n/**\n * @export\n */\nB.prototype.doStuff = function() {\n  this.label = this.label;\n  var /** @type {string} */ theLabel = this.label;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nB.prototype._label = null;\n\n\n" +
 				"B.prototype.get__label = function() {\n  return this._label;\n};\n\n\n" +
 				"B.prototype.set__label = function(value) {\n  this._label = value;\n};\n\n\n" +
 				"Object.defineProperties(B.prototype, /** @lends {B.prototype} */ {\n/**\n  * @export\n  * @type {string} */\nlabel: {\n" +
@@ -106,10 +106,10 @@
                 "import custom.custom_namespace;use namespace custom_namespace;public class B { public function B() {}; public function doStuff():void {var theLabel:String = label; label = theLabel;}; private var _label:String; custom_namespace function get label():String {return _label}; custom_namespace function set label(value:String):void {_label = value};}",
                 IClassNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitClass(node);
-        String expected = "/**\n * @constructor\n */\nB = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('B', B);\n\n\n/**\n * @export\n */\nB.prototype.doStuff = function() {\n  var /** @type {string} */ theLabel = this[\"http://ns.apache.org/2017/custom/namespace::label\"];\n  this[\"http://ns.apache.org/2017/custom/namespace::label\"] = theLabel;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nB.prototype._label;\n\n\n" +
-				"B.prototype[\"http://ns.apache.org/2017/custom/namespace::get__label\"] = function() {\n  return this._label;\n};\n\n\n" +
-				"B.prototype[\"http://ns.apache.org/2017/custom/namespace::set__label\"] = function(value) {\n  this._label = value;\n};\n\n\n" +
-        		"Object.defineProperties(B.prototype, /** @lends {B.prototype} */ {\n/**\n  * @export\n  * @type {string} */\n\"http://ns.apache.org/2017/custom/namespace::label\": {\nget: B.prototype[\"http://ns.apache.org/2017/custom/namespace::get__label\"],\nset: B.prototype[\"http://ns.apache.org/2017/custom/namespace::set__label\"]}}\n);";
+        String expected = "/**\n * @constructor\n */\nB = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('B', B);\n\n\n/**\n * @export\n */\nB.prototype.doStuff = function() {\n  var /** @type {string} */ theLabel = this.http_$$ns_apache_org$2017$custom$namespace__label;\n  this.http_$$ns_apache_org$2017$custom$namespace__label = theLabel;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nB.prototype._label = null;\n\n\n" +
+				"B.prototype.http_$$ns_apache_org$2017$custom$namespace__get__label = function() {\n  return this._label;\n};\n\n\n" +
+				"B.prototype.http_$$ns_apache_org$2017$custom$namespace__set__label = function(value) {\n  this._label = value;\n};\n\n\n" +
+        		"Object.defineProperties(B.prototype, /** @lends {B.prototype} */ {\n/**\n  * @export\n  * @type {string} */\nhttp_$$ns_apache_org$2017$custom$namespace__label: {\nget: B.prototype.http_$$ns_apache_org$2017$custom$namespace__get__label,\nset: B.prototype.http_$$ns_apache_org$2017$custom$namespace__set__label}}\n);";
         assertOut(expected);
     }
 
@@ -120,7 +120,7 @@
                 "public function doStuff():void {label = 'hello, bye'; var theLabel:String = label;}; private var _label:String; [Bindable] public function get label():String {return _label}; public function set label(value:String):void {_label = value}; ",
                 IClassNode.class, WRAP_LEVEL_CLASS);
         asBlockWalker.visitClass(node);
-        String expected = "/**\n * @constructor\n */\nRoyaleTest_A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('RoyaleTest_A', RoyaleTest_A);\n\n\n/**\n * @export\n */\nRoyaleTest_A.prototype.doStuff = function() {\n  this.label = 'hello, bye';\n  var /** @type {string} */ theLabel = this.label;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nRoyaleTest_A.prototype._label;\n\n\n" +
+        String expected = "/**\n * @constructor\n */\nRoyaleTest_A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('RoyaleTest_A', RoyaleTest_A);\n\n\n/**\n * @export\n */\nRoyaleTest_A.prototype.doStuff = function() {\n  this.label = 'hello, bye';\n  var /** @type {string} */ theLabel = this.label;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nRoyaleTest_A.prototype._label = null;\n\n\n" +
         		"RoyaleTest_A.prototype.get__label = function() {\n  return this._label;\n};\n\n\n" +
 				"RoyaleTest_A.prototype.bindable__set__label = function(value) {\n  this._label = value;\n};\n\n\n" +
         		"RoyaleTest_A.prototype.set__label = function(value) {\nvar oldValue = this.get__label();\nif (oldValue != value) {\nthis.bindable__set__label(value);\n" +
@@ -138,7 +138,7 @@
                 "public function doStuff():void {label = 'hello, bye'; var theLabel:String = label;}; private var _label:String; [Bindable(\"change\")] public function get label():String {return _label}; public function set label(value:String):void {_label = value}; ",
                 IClassNode.class, WRAP_LEVEL_CLASS);
         asBlockWalker.visitClass(node);
-        String expected = "/**\n * @constructor\n */\nRoyaleTest_A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('RoyaleTest_A', RoyaleTest_A);\n\n\n/**\n * @export\n */\nRoyaleTest_A.prototype.doStuff = function() {\n  this.label = 'hello, bye';\n  var /** @type {string} */ theLabel = this.label;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nRoyaleTest_A.prototype._label;\n\n\n" +
+        String expected = "/**\n * @constructor\n */\nRoyaleTest_A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('RoyaleTest_A', RoyaleTest_A);\n\n\n/**\n * @export\n */\nRoyaleTest_A.prototype.doStuff = function() {\n  this.label = 'hello, bye';\n  var /** @type {string} */ theLabel = this.label;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nRoyaleTest_A.prototype._label = null;\n\n\n" +
 				"RoyaleTest_A.prototype.get__label = function() {\n  return this._label;\n};\n\n\n" +
 				"RoyaleTest_A.prototype.set__label = function(value) {\n  this._label = value;\n};\n\n\n" +
         		"Object.defineProperties(RoyaleTest_A.prototype, /** @lends {RoyaleTest_A.prototype} */ {\n/**\n  * @export\n  * @type {string} */\n" +
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleClass.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleClass.java
index f223030..788cfda 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleClass.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleClass.java
@@ -149,6 +149,87 @@
     }
 
     @Test
+    public void testMethod_returnIntWithVariableNoCoercion()
+    {
+        IClassNode node = getClassNode("public class B {public function B() {}; public function foo():int { var a:int = 123; return a; };}");
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', org.apache.royale.B);\n\n\n/**\n * @export\n */\norg.apache.royale.B.prototype.foo = function() {\n  var a /** @type {number} */ = 123.4;\n  return a;\n};";
+        assertOut(expected);
+    }
+
+    @Test
+    public void testMethod_returnIntWithVariableCoercion()
+    {
+        IClassNode node = getClassNode("public class B {public function B() {}; public function foo():int { var a:Number = 123.4; return a; };}");
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', org.apache.royale.B);\n\n\n/**\n * @export\n */\norg.apache.royale.B.prototype.foo = function() {\n  var a /** @type {number} */ = 123.4;\n  return (a) >> 0;\n};";
+        assertOut(expected);
+    }
+
+    @Test
+    public void testMethod_returnIntWithLiteralCoercion()
+    {
+        IClassNode node = getClassNode("public class B {public function B() {}; public function foo():int { return 123.4 };}");
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', org.apache.royale.B);\n\n\n/**\n * @export\n */\norg.apache.royale.B.prototype.foo = function() {\n  return (123.4) >> 0;\n};";
+        assertOut(expected);
+    }
+
+    @Test
+    public void testMethod_returnUintWithVariableNoCoercion()
+    {
+        IClassNode node = getClassNode("public class B {public function B() {}; public function foo():uint { var a:uint = 123; return a; };}");
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', org.apache.royale.B);\n\n\n/**\n * @export\n */\norg.apache.royale.B.prototype.foo = function() {\n  var a /** @type {number} */ = 123.4;\n  return a;\n};";
+        assertOut(expected);
+    }
+
+    @Test
+    public void testMethod_returnUintWithVariableCoercion()
+    {
+        IClassNode node = getClassNode("public class B {public function B() {}; public function foo():uint { var a:Number = 123.4; return a; };}");
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', org.apache.royale.B);\n\n\n/**\n * @export\n */\norg.apache.royale.B.prototype.foo = function() {\n  var a /** @type {number} */ = 123.4;\n  return (a) >>> 0;\n};";
+        assertOut(expected);
+    }
+
+    @Test
+    public void testMethod_returnUintWithLiteralCoercion()
+    {
+        IClassNode node = getClassNode("public class B {public function B() {}; public function foo():uint { return 123.4 };}");
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', org.apache.royale.B);\n\n\n/**\n * @export\n */\norg.apache.royale.B.prototype.foo = function() {\n  return (123.4) >>> 0;\n};";
+        assertOut(expected);
+    }
+
+    @Test
+    public void testMethod_returnBooleanWithVariableNoCoercion()
+    {
+        IClassNode node = getClassNode("public class B {public function B() {}; public function foo():Boolean { var a:Boolean = true; return a; };}");
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', org.apache.royale.B);\n\n\n/**\n * @export\n */\norg.apache.royale.B.prototype.foo = function() {\n  var a /** @type {number} */ = 123.4;\n  return a;\n};";
+        assertOut(expected);
+    }
+
+    @Test
+    public void testMethod_returnBooleanWithVariableCoercion()
+    {
+        IClassNode node = getClassNode("public class B {public function B() {}; public function foo():Boolean { var a:Number = 123.4; return a; };}");
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', org.apache.royale.B);\n\n\n/**\n * @export\n */\norg.apache.royale.B.prototype.foo = function() {\n  var a /** @type {number} */ = 123.4;\n  return !!(a);\n};";
+        assertOut(expected);
+    }
+
+    @Test
+    public void testMethod_returnBooleanWithLiteralNoCoercion()
+    {
+        IClassNode node = getClassNode("public class B {public function B() {}; public function foo():Boolean { return 123.4 };}");
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', org.apache.royale.B);\n\n\n/**\n * @export\n */\norg.apache.royale.B.prototype.foo = function() {\n  return true;\n};";
+        assertOut(expected);
+    }
+
+    @Test
     public void testMethod_override()
     {
         IClassNode node = getClassNode("public class B {public function B() {}; override public function foo():void {};}");
@@ -198,10 +279,113 @@
     {
         IClassNode node = getClassNode("import custom.custom_namespace; use namespace custom_namespace; public class B {public function B() {}; custom_namespace function foo():void {};}");
         asBlockWalker.visitClass(node);
-        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', org.apache.royale.B);\n\n\n/**\n */\norg.apache.royale.B.prototype[\"http://ns.apache.org/2017/custom/namespace::foo\"] = function() {\n};";
+        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', org.apache.royale.B);\n\n\n/**\n * @export\n */\norg.apache.royale.B.prototype.http_$$ns_apache_org$2017$custom$namespace__foo = function() {\n};";
         assertOut(expected);
     }
 
+    @Test
+    public void testInnerClassReferencingInnerClass()
+    {
+    	FileNode node = (FileNode)getNode("package org.apache.royale {\npublic class B {public function B() {}; }} class A {public function get a():A {return null}}", FileNode.class, 0);
+        asBlockWalker.visitFile(node);
+        String expected = "/**\n * org.apache.royale.B\n *\n * @fileoverview\n *\n * @suppress {checkTypes|accessControls}\n */\n\ngoog.provide('org.apache.royale.B');\ngoog.provide('org.apache.royale.B.A');\n\n\n\n" +
+                          "/**\n * @constructor\n */\norg.apache.royale.B = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', org.apache.royale.B);" +
+                          "\n\n\n/**\n" + 
+                          " * Metadata\n" + 
+                          " *\n" + 
+                          " * @type {Object.<string, Array.<Object>>}\n" + 
+                          " */\n" + 
+                          "org.apache.royale.B.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'B', qName: 'org.apache.royale.B', kind: 'class' }] };\n" + 
+                          "\n" + 
+                          "\n" + 
+                          "\n" + 
+                          "/**\n" + 
+                          " * Reflection\n" + 
+                          " *\n" + 
+                          " * @return {Object.<string, Function>}\n" + 
+                          " */\n" + 
+                          "org.apache.royale.B.prototype.ROYALE_REFLECTION_INFO = function () {\n" + 
+                          "  return {\n" + 
+                          "    variables: function () {return {};},\n" + 
+                          "    accessors: function () {return {};},\n" + 
+                          "    methods: function () {\n" + 
+                          "      return {\n" + 
+                          "        'B': { type: '', declaredBy: 'org.apache.royale.B'}\n" + 
+                          "      };\n" + 
+                          "    }\n" + 
+                          "  };\n" + 
+                          "};\n" + 
+                          "/**\n" + 
+                          " * @export\n" + 
+                          " * @const\n" + 
+                          " * @type {number}\n" + 
+                          " */\n" + 
+                          "org.apache.royale.B.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;\n" + 
+                          "\n" + 
+                          "\n" + 
+                          "\n" + 
+                          "/**\n" + 
+                          " * @constructor\n" + 
+                          " */\n" + 
+                          "org.apache.royale.B.A = function() {\n" + 
+                          "};\n" + 
+                          "\n" + 
+                          "\n" + 
+                          "/**\n" + 
+                          " * Prevent renaming of class. Needed for reflection.\n" + 
+                          " */\n" + 
+                          "goog.exportSymbol('org.apache.royale.B.A', org.apache.royale.B.A);\n" + 
+                          "\n" + 
+                          "\n" + 
+                          "org.apache.royale.B.A.prototype.get__a = function() {\n" + 
+                          "  return null;\n" + 
+                          "};\n" + 
+                          "\n" + 
+                          "\n" + 
+                          "Object.defineProperties(org.apache.royale.B.A.prototype, /** @lends {org.apache.royale.B.A.prototype} */ {\n" + 
+                          "/**\n" + 
+                          "  * @export\n" + 
+                          "  * @type {org.apache.royale.B.A} */\n" + 
+                          "a: {\n" + 
+                          "get: org.apache.royale.B.A.prototype.get__a}}\n" + 
+                          ");\n" + 
+                          "\n" + 
+                          "\n" + 
+                          "/**\n" + 
+                          " * Metadata\n" + 
+                          " *\n" + 
+                          " * @type {Object.<string, Array.<Object>>}\n" + 
+                          " */\n" + 
+                          "org.apache.royale.B.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'org.apache.royale.B.A', kind: 'class' }] };\n" + 
+                          "\n" + 
+                          "\n" + 
+                          "\n" + 
+                          "/**\n" + 
+                          " * Reflection\n" + 
+                          " *\n" + 
+                          " * @return {Object.<string, Function>}\n" + 
+                          " */\n" + 
+                          "org.apache.royale.B.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" + 
+                          "  return {\n" + 
+                          "    variables: function () {return {};},\n" + 
+                          "    accessors: function () {\n" + 
+                          "      return {\n" + 
+                          "        'a': { type: 'org.apache.royale.B.A', access: 'readonly', declaredBy: 'org.apache.royale.B.A'}\n" + 
+                          "      };\n" + 
+                          "    },\n" + 
+                          "    methods: function () {return {};}\n" + 
+                          "  };\n" + 
+                          "};\n" + 
+                          "/**\n" + 
+                          " * @export\n" + 
+                          " * @const\n" + 
+                          " * @type {number}\n" + 
+                          " */\n" + 
+                          "org.apache.royale.B.A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;\n" + 
+                          "";
+        assertOutWithMetadata(expected);
+    }
+
     @Override
     @Test
     public void testExtendsConstructor_withArguments()
@@ -509,15 +693,15 @@
         		"org.apache.royale.A.prototype.set__foo3 = function(value) {\n};\n\n\n" +
         		"org.apache.royale.A.prototype.get__foo5 = function() {\n  return null;\n};\n\n\n" +
         		"org.apache.royale.A.prototype.set__foo5 = function(value) {\n};\n\n\n" +
-        		"org.apache.royale.A.prototype[\"http://ns.apache.org/2017/custom/namespace::get__foo6\"] = function() {\n  return null;\n};\n\n\n" +
-        		"org.apache.royale.A.prototype[\"http://ns.apache.org/2017/custom/namespace::set__foo6\"] = function(value) {\n};\n\n\n" +
+        		"org.apache.royale.A.prototype.http_$$ns_apache_org$2017$custom$namespace__get__foo6 = function() {\n  return null;\n};\n\n\n" +
+        		"org.apache.royale.A.prototype.http_$$ns_apache_org$2017$custom$namespace__set__foo6 = function(value) {\n};\n\n\n" +
         		"Object.defineProperties(org.apache.royale.A.prototype, /** @lends {org.apache.royale.A.prototype} */ {\n/**\n  * @export\n  * @type {Object} */\n" +
         		    "foo1: {\nget: org.apache.royale.A.prototype.get__foo1,\nset: org.apache.royale.A.prototype.set__foo1},\n/**\n  * @export\n  * @type {Object} */\n" +
         		    "foo2: {\nget: org.apache.royale.A.prototype.get__foo2,\nset: org.apache.royale.A.prototype.set__foo2},\n/**\n  * @export\n  * @type {Object} */\n" +
         		    "foo3: {\nget: org.apache.royale.A.prototype.get__foo3,\nset: org.apache.royale.A.prototype.set__foo3},\n/**\n  * @export\n  * @type {Object} */\n" +
         		    "foo5: {\nget: org.apache.royale.A.prototype.get__foo5,\nset: org.apache.royale.A.prototype.set__foo5},\n/**\n  * @export\n  * @type {Object} */\n" +
-        		    "\"http://ns.apache.org/2017/custom/namespace::foo6\": {\nget: org.apache.royale.A.prototype[\"http://ns.apache.org/2017/custom/namespace::get__foo6\"],\n" +
-        		    																"set: org.apache.royale.A.prototype[\"http://ns.apache.org/2017/custom/namespace::set__foo6\"]}}\n);");
+        		    "http_$$ns_apache_org$2017$custom$namespace__foo6: {\nget: org.apache.royale.A.prototype.http_$$ns_apache_org$2017$custom$namespace__get__foo6,\n" +
+        		    																"set: org.apache.royale.A.prototype.http_$$ns_apache_org$2017$custom$namespace__set__foo6}}\n);");
     }
 
     @Override
@@ -535,7 +719,7 @@
                 + "public static function foo7(value:Object):void{}"
                 + "custom_namespace static function foo7(value:Object):void{}" + "}");
         asBlockWalker.visitClass(node);
-        assertOut("/**\n * @constructor\n */\norg.apache.royale.A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('org.apache.royale.A', org.apache.royale.A);\n\n\n/**\n * @export\n * @return {Object}\n */\norg.apache.royale.A.prototype.foo1 = function() {\n  return null;\n};\n\n\n/**\n * @export\n * @return {Object}\n */\norg.apache.royale.A.prototype.foo1a = function() {\n  return null;\n};\n\n\n/**\n * @export\n * @override\n */\norg.apache.royale.A.prototype.foo1b = function() {\n  return org.apache.royale.A.superClass_.foo1b.apply(this);\n};\n\n\n/**\n * @protected\n * @param {Object} value\n */\norg.apache.royale.A.prototype.foo2 = function(value) {\n};\n\n\n/**\n * @private\n * @param {Object} value\n */\norg.apache.royale.A.prototype.foo3 = function(value) {\n};\n\n\n/**\n * @param {Object} value\n */\norg.apache.royale.A.prototype.foo5 = function(value) {\n};\n\n\n/**\n * @param {Object} value\n */\norg.apache.royale.A.prototype[\"http://ns.apache.org/2017/custom/namespace::foo6\"] = function(value) {\n};\n\n\n/**\n * @export\n * @param {Object} value\n */\norg.apache.royale.A.foo7 = function(value) {\n};\n\n\n/**\n * @param {Object} value\n */\norg.apache.royale.A[\"http://ns.apache.org/2017/custom/namespace::foo7\"] = function(value) {\n};");
+        assertOut("/**\n * @constructor\n */\norg.apache.royale.A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('org.apache.royale.A', org.apache.royale.A);\n\n\n/**\n * @export\n * @return {Object}\n */\norg.apache.royale.A.prototype.foo1 = function() {\n  return null;\n};\n\n\n/**\n * @export\n * @return {Object}\n */\norg.apache.royale.A.prototype.foo1a = function() {\n  return null;\n};\n\n\n/**\n * @export\n * @override\n */\norg.apache.royale.A.prototype.foo1b = function() {\n  return org.apache.royale.A.superClass_.foo1b.apply(this);\n};\n\n\n/**\n * @protected\n * @param {Object} value\n */\norg.apache.royale.A.prototype.foo2 = function(value) {\n};\n\n\n/**\n * @private\n * @param {Object} value\n */\norg.apache.royale.A.prototype.foo3 = function(value) {\n};\n\n\n/**\n * @export\n * @param {Object} value\n */\norg.apache.royale.A.prototype.foo5 = function(value) {\n};\n\n\n/**\n * @export\n * @param {Object} value\n */\norg.apache.royale.A.prototype.http_$$ns_apache_org$2017$custom$namespace__foo6 = function(value) {\n};\n\n\n/**\n * @export\n * @param {Object} value\n */\norg.apache.royale.A.foo7 = function(value) {\n};\n\n\n/**\n * @export\n * @param {Object} value\n */\norg.apache.royale.A.http_$$ns_apache_org$2017$custom$namespace__foo7 = function(value) {\n};");
     }
 
     @Test
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleEmitter.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleEmitter.java
index e8c40a8..94d39f5 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleEmitter.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleEmitter.java
@@ -59,92 +59,98 @@
         IFileNode node = compileAS(code);
         asBlockWalker.visitFile(node);
 	        assertOutWithMetadata("/**\n" +
-        		" * com.example.components.MyEventTarget\n" +
-        		" *\n" +
-        		" * @fileoverview\n" +
-        		" *\n" +
-        		" * @suppress {checkTypes|accessControls}\n" +
-        		" */\n" +
-        		"\n" +
-        		"goog.provide('com.example.components.MyEventTarget');\n" +
-        		"\n" +
-        		"goog.require('custom.TestImplementation');\n" +
-        		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * @constructor\n" +
-        		" * @extends {custom.TestImplementation}\n" +
-        		" */\n" +
-        		"com.example.components.MyEventTarget = function() {\n" +
-        		"  com.example.components.MyEventTarget.base(this, 'constructor');\n" +
-        		"  if (foo() != 42) {\n" +
-        		"    bar();\n" +
-        		"  }\n" +
-        		"};\n" +
-        		"goog.inherits(com.example.components.MyEventTarget, custom.TestImplementation);\n" +
-          		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Prevent renaming of class. Needed for reflection.\n" +
-        		" */\n" +
-        		"goog.exportSymbol('com.example.components.MyEventTarget', com.example.components.MyEventTarget);\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * @private\n" +
-        		" * @type {string}\n" +
-        		" */\n" +
-        		"com.example.components.MyEventTarget.prototype._privateVar = \"do \";\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * @export\n" +
-        		" * @type {number}\n" +
-        		" */\n" +
-        		"com.example.components.MyEventTarget.prototype.publicProperty = 100;\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * @export\n" +
-        		" * @param {string} value\n" +
-        		" * @return {string}\n" +
-        		" */\n" +
-        		"com.example.components.MyEventTarget.prototype.myFunction = function(value) {\n" +
-        		"  return \"Don't \" + this._privateVar + value;\n" +
-        		"};\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Metadata\n" +
-        		" *\n" +
-        		" * @type {Object.<string, Array.<Object>>}\n" +
-        		" */\n" +
-        		"com.example.components.MyEventTarget.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'MyEventTarget', qName: 'com.example.components.MyEventTarget', kind: 'class' }] };\n" +
-          		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Reflection\n" +
-        		" *\n" +
-        		" * @return {Object.<string, Function>}\n" +
-        		" */\n" +
-        		"com.example.components.MyEventTarget.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-        		"  return {\n" +
-        		"    variables: function () {\n" +
-        		"      return {\n" +
-        		"        'publicProperty': { type: 'Number'}\n" +
-        		"      };\n" + 
-        		"    },\n" +
-        		"    accessors: function () {return {};},\n" +
-        		"    methods: function () {\n" +
-        		"      return {\n" +
-        		"        'MyEventTarget': { type: '', declaredBy: 'com.example.components.MyEventTarget'},\n" +
-        		"        'myFunction': { type: 'String', declaredBy: 'com.example.components.MyEventTarget', parameters: function () { return [  { index: 1, type: 'String', optional: false } ]; }}\n" +
-        		"      };\n" +
-        		"    }\n" +
-        		"  };\n" +
-        		"};\n");
+					" * com.example.components.MyEventTarget\n" +
+					" *\n" +
+					" * @fileoverview\n" +
+					" *\n" +
+					" * @suppress {checkTypes|accessControls}\n" +
+					" */\n" +
+					"\n" +
+					"goog.provide('com.example.components.MyEventTarget');\n" +
+					"\n" +
+					"goog.require('custom.TestImplementation');\n" +
+					"\n" +
+					"\n" +
+					"\n" +
+					"/**\n" +
+					" * @constructor\n" +
+					" * @extends {custom.TestImplementation}\n" +
+					" */\n" +
+					"com.example.components.MyEventTarget = function() {\n" +
+					"  com.example.components.MyEventTarget.base(this, 'constructor');\n" +
+					"  if (foo() != 42) {\n" +
+					"    bar();\n" +
+					"  }\n" +
+					"};\n" +
+					"goog.inherits(com.example.components.MyEventTarget, custom.TestImplementation);\n" +
+					"\n" +
+					"\n" +
+					"/**\n" +
+					" * Prevent renaming of class. Needed for reflection.\n" +
+					" */\n" +
+					"goog.exportSymbol('com.example.components.MyEventTarget', com.example.components.MyEventTarget);\n" +
+					"\n" +
+					"\n" +
+					"/**\n" +
+					" * @private\n" +
+					" * @type {string}\n" +
+					" */\n" +
+					"com.example.components.MyEventTarget.prototype._privateVar = \"do \";\n" +
+			"\n" +
+			"\n" +
+			"/**\n" +
+			" * @export\n" +
+			" * @type {number}\n" +
+			" */\n" +
+			"com.example.components.MyEventTarget.prototype.publicProperty = 100;\n" +
+			"\n" +
+			"\n" +
+			"/**\n" +
+			" * @export\n" +
+			" * @param {string} value\n" +
+			" * @return {string}\n" +
+			" */\n" +
+			"com.example.components.MyEventTarget.prototype.myFunction = function(value) {\n" +
+			"  return \"Don't \" + this._privateVar + value;\n" +
+		"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Metadata\n" +
+				" *\n" +
+				" * @type {Object.<string, Array.<Object>>}\n" +
+				" */\n" +
+				"com.example.components.MyEventTarget.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'MyEventTarget', qName: 'com.example.components.MyEventTarget', kind: 'class' }] };\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"com.example.components.MyEventTarget.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
+				"    variables: function () {\n" +
+				"      return {\n" +
+				"        'publicProperty': { type: 'Number', get_set: function (/** com.example.components.MyEventTarget */ inst, /** * */ v) {return v !== undefined ? inst.publicProperty = v : inst.publicProperty;}}\n" +
+				"      };\n" +
+				"    },\n" +
+				"    accessors: function () {return {};},\n" +
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'MyEventTarget': { type: '', declaredBy: 'com.example.components.MyEventTarget'},\n" +
+				"        'myFunction': { type: 'String', declaredBy: 'com.example.components.MyEventTarget', parameters: function () { return [ { index: 1, type: 'String', optional: false } ]; }}\n" +
+				"      };\n" +
+				"    }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"com.example.components.MyEventTarget.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;\n");
     }
 
     @Override
@@ -156,49 +162,55 @@
         IFileNode node = compileAS(code);
         asBlockWalker.visitFile(node);
         assertOutWithMetadata("/**\n" +
-        		" * com.example.components.TestInterface\n" +
-        		" *\n" +
-        		" * @fileoverview\n" +
-        		" *\n" +
-        		" * @suppress {checkTypes|accessControls}\n" +
-        		" */\n" +
-        		"\n" +
-        		"goog.provide('com.example.components.TestInterface');\n" +
-        		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * @interface\n" +
-        		" */\ncom.example.components.TestInterface = function() {\n" +
-        		"};\n" +
-          		"\n" +
+				" * com.example.components.TestInterface\n" +
+				" *\n" +
+				" * @fileoverview\n" +
+				" *\n" +
+				" * @suppress {checkTypes|accessControls}\n" +
+				" */\n" +
+				"\n" +
+				"goog.provide('com.example.components.TestInterface');\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @interface\n" +
+				" */\ncom.example.components.TestInterface = function() {\n" +
+				"};\n" +
+				"\n" +
 				"\n" +
 				"/**\n" +
 				" * Prevent renaming of class. Needed for reflection.\n" +
 				" */\n" +
 				"goog.exportSymbol('com.example.components.TestInterface', com.example.components.TestInterface);\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Metadata\n" +
-        		" *\n" +
-        		" * @type {Object.<string, Array.<Object>>}\n" +
-        		" */\n" +
-        		"com.example.components.TestInterface.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'TestInterface', qName: 'com.example.components.TestInterface', kind: 'interface' }] };\n" +
 				"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Reflection\n" +
-        		" *\n" +
-        		" * @return {Object.<string, Function>}\n" +
-        		" */\n" +
-        		"com.example.components.TestInterface.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-        		"  return {\n" +
-        		"    accessors: function () {return {};},\n" +
-        		"    methods: function () {return {};}\n" +
-        		"  };\n" +
-        		"};\n");
+				"\n" +
+				"/**\n" +
+				" * Metadata\n" +
+				" *\n" +
+				" * @type {Object.<string, Array.<Object>>}\n" +
+				" */\n" +
+				"com.example.components.TestInterface.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'TestInterface', qName: 'com.example.components.TestInterface', kind: 'interface' }] };\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"com.example.components.TestInterface.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
+				"    accessors: function () {return {};},\n" +
+				"    methods: function () {return {};}\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"com.example.components.TestInterface.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;\n");
     }
 
     @Override
@@ -254,7 +266,13 @@
 				"    accessors: function () {return {};},\n" +
 				"    methods: function () {return {};}\n" +
 				"  };\n" +
-				"};\n");
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"com.example.components.TestClass.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;\n");
     }
     
     @Test
@@ -283,9 +301,9 @@
 				"\n" +
 				"\n" +
 				"/**\n" +
-        	    " * <inject_html>\n" +
+				" * <inject_html>\n" +
 				" * This will be injected.\n" +
-        		" * </inject_html>\n" +
+				" * </inject_html>\n" +
 				" * @constructor\n" +
 				" */\n" +
 				"com.example.components.TestClass = function() {\n" +
@@ -322,7 +340,13 @@
 				"      };\n" +
 				"    }\n" +
 				"  };\n" +
-				"};\n");
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"com.example.components.TestClass.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;\n");
     }
     
 
@@ -330,9 +354,9 @@
     @Test
     public void testDefaultParameter()
     {
-        IFunctionNode node = getMethodWithPackage("function method1(p1:int, p2:int, p3:int = 3, p4:int = 4):int{return p1 + p2 + p3 + p4;}");
+        IFunctionNode node = getMethodWithPackage("function method1(p1:Number, p2:Number, p3:Number = 3, p4:Number = 4):Number{return p1 + p2 + p3 + p4;}");
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @param {number} p1\n * @param {number} p2\n * @param {number=} p3\n * @param {number=} p4\n * @return {number}\n */\n"
+        assertOut("/**\n * @export\n * @param {number} p1\n * @param {number} p2\n * @param {number=} p3\n * @param {number=} p4\n * @return {number}\n */\n"
                 + "foo.bar.RoyaleTest_A.prototype.method1 = function(p1, p2, p3, p4) {\n"
                 + "  p3 = typeof p3 !== 'undefined' ? p3 : 3;\n"
                 + "  p4 = typeof p4 !== 'undefined' ? p4 : 4;\n"
@@ -345,7 +369,7 @@
     {
         IFunctionNode node = getMethodWithPackage("function method1(bar:int = 42, bax:int = 4):void{if (a) foo();}");
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @param {number=} bar\n * @param {number=} bax\n */\n"
+        assertOut("/**\n * @export\n * @param {number=} bar\n * @param {number=} bax\n */\n"
                 + "foo.bar.RoyaleTest_A.prototype.method1 = function(bar, bax) {\n"
                 + "  bar = typeof bar !== 'undefined' ? bar : 42;\n"
                 + "  bax = typeof bax !== 'undefined' ? bax : 4;\n"
@@ -358,7 +382,7 @@
     {
         IFunctionNode node = getMethodWithPackage("function method1(p1:int, p2:int, p3:int = 3, p4:int = 4):int{}");
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @param {number} p1\n * @param {number} p2\n * @param {number=} p3\n * @param {number=} p4\n * @return {number}\n */\n"
+        assertOut("/**\n * @export\n * @param {number} p1\n * @param {number} p2\n * @param {number=} p3\n * @param {number=} p4\n * @return {number}\n */\n"
                 + "foo.bar.RoyaleTest_A.prototype.method1 = function(p1, p2, p3, p4) {\n"
                 + "  p3 = typeof p3 !== 'undefined' ? p3 : 3;\n"
                 + "  p4 = typeof p4 !== 'undefined' ? p4 : 4;\n}");
@@ -370,7 +394,7 @@
     {
         IFunctionNode node = getMethodWithPackage("function method1(bar:int):int{\n}");
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @param {number} bar\n * @return {number}\n */\n"
+        assertOut("/**\n * @export\n * @param {number} bar\n * @return {number}\n */\n"
                 + "foo.bar.RoyaleTest_A.prototype.method1 = function(bar) {\n}");
     }
 
@@ -380,7 +404,7 @@
     {
         IFunctionNode node = getMethodWithPackage("function method1(bar:int, baz:String, goo:Array):void{\n}");
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @param {number} bar\n * @param {string} baz\n * @param {Array} goo\n */\n"
+        assertOut("/**\n * @export\n * @param {number} bar\n * @param {string} baz\n * @param {Array} goo\n */\n"
                 + "foo.bar.RoyaleTest_A.prototype.method1 = function(bar, baz, goo) {\n}");
     }
 
@@ -390,7 +414,7 @@
     {
         IFunctionNode node = getMethodWithPackage("/**\n * This is copied from ASDoc.\n */\nfunction method1(bar:int, baz:String, goo:Array):void{\n}");
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * This is copied from ASDoc.\n * @param {number} bar\n * @param {string} baz\n * @param {Array} goo\n */\n"
+        assertOut("/**\n * This is copied from ASDoc.\n * @export\n * @param {number} bar\n * @param {string} baz\n * @param {Array} goo\n */\n"
                 + "foo.bar.RoyaleTest_A.prototype.method1 = function(bar, baz, goo) {\n}");
     }
 
@@ -399,7 +423,7 @@
     {
         IFunctionNode node = getMethodWithPackage("/** This is copied from ASDoc. */\nfunction method1(bar:int, baz:String, goo:Array):void{\n}");
         asBlockWalker.visitFunction(node);
-        assertOut("/** This is copied from ASDoc. \n * @param {number} bar\n * @param {string} baz\n * @param {Array} goo\n */\n"
+        assertOut("/** This is copied from ASDoc. \n * @export\n * @param {number} bar\n * @param {string} baz\n * @param {Array} goo\n */\n"
                 + "foo.bar.RoyaleTest_A.prototype.method1 = function(bar, baz, goo) {\n}");
     }
 
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleExpressions.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleExpressions.java
index 399c93e..8ee8ab9 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleExpressions.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleExpressions.java
@@ -32,11 +32,12 @@
 import org.apache.royale.compiler.internal.tree.as.NodeBase;
 import org.apache.royale.compiler.tree.as.IBinaryOperatorNode;
 import org.apache.royale.compiler.tree.as.IClassNode;
+import org.apache.royale.compiler.tree.as.IDynamicAccessNode;
 import org.apache.royale.compiler.tree.as.IFileNode;
 import org.apache.royale.compiler.tree.as.IFunctionCallNode;
 import org.apache.royale.compiler.tree.as.IFunctionNode;
-import org.apache.royale.compiler.tree.as.IGetterNode;
 import org.apache.royale.compiler.tree.as.IMemberAccessExpressionNode;
+import org.apache.royale.compiler.tree.as.IReturnNode;
 import org.apache.royale.compiler.tree.as.IVariableNode;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -63,6 +64,33 @@
         super.setUp();
     }
 
+    @Test
+	public void testVisitDynamicAccessString()
+    {
+        IDynamicAccessNode node = (IDynamicAccessNode) getNode(
+                "public class KnownMember { public function KnownMember() { this[\"knownMember\"] = 4; } public var knownMember:Number; }", IDynamicAccessNode.class, WRAP_LEVEL_PACKAGE);
+        asBlockWalker.visitDynamicAccess(node);
+        assertOut("this[\"knownMember\"]");
+    }
+    
+    @Test
+	public void testVisitDynamicAccessQName()
+    {
+        IDynamicAccessNode node = (IDynamicAccessNode) getNode(
+                "public class KnownMember { public function KnownMember() { var q:QName; this[q] = 4; } public var knownMember:Number; }", IDynamicAccessNode.class, WRAP_LEVEL_PACKAGE);
+        asBlockWalker.visitDynamicAccess(node);
+        assertOut("this[q.objectAccessFormat()]");
+    }
+    
+    @Test
+	public void testVisitDynamicAccessQName2()
+    {
+        IDynamicAccessNode node = (IDynamicAccessNode) getNode(
+                "public class KnownMember { public function KnownMember() { this[new QName(new Namespace('ns'), 'knownMember')] = 4; } public var knownMember:Number; }", IDynamicAccessNode.class, WRAP_LEVEL_PACKAGE);
+        asBlockWalker.visitDynamicAccess(node);
+        assertOut("this[new QName(new Namespace('ns'), 'knownMember').objectAccessFormat()]");
+    }
+    
     @Ignore
     @Override
     @Test
@@ -78,9 +106,9 @@
     @Test
     public void testVisitLanguageIdentifierNode_SuperGetter()
     {
-        IClassNode node = (IClassNode)getNode("public function get defaultPrevented():Boolean " +
+        IClassNode node = (IClassNode)getNode("public function get defaultPrevented():Object " +
         		                       "{ return super.isDefaultPrevented(); }" + 
-        		                       "override public function isDefaultPrevented():Boolean" +
+        		                       "override public function isDefaultPrevented():Object" +
                                        "{ return defaultPrevented; }", IClassNode.class);
         // getters and setters don't get output until the class is output so you can't just visit the accessorNode
         asBlockWalker.visitClass(node);
@@ -95,14 +123,13 @@
         		  "  var self = this;\n" +
         		  "  ;\n" +
         		  "  function isDefaultPrevented() {\n" +
-        		  "    return defaultPrevented;\n  };\n" +
-        		  "  ;\n  \n" +
+        		  "    return defaultPrevented;\n  };\n  \n" +
         		  "};\n\n\n" +
         		  "RoyaleTest_A.prototype.get__defaultPrevented = function() {\n" +
         		  "  return RoyaleTest_A.superClass_.isDefaultPrevented.apply(this);\n" +
         		  "};\n\n\n" +
         		  "Object.defineProperties(RoyaleTest_A.prototype, /** @lends {RoyaleTest_A.prototype} */ {\n" +
-        		  "/**\n  * @export\n  * @type {boolean} */\n" +
+        		  "/**\n  * @export\n  * @type {Object} */\n" +
         		  "defaultPrevented: {\nget: RoyaleTest_A.prototype.get__defaultPrevented}}\n);");
     }
 
@@ -130,7 +157,7 @@
         IFunctionNode node = (IFunctionNode)getNode("import custom.TestProxy;import custom.custom_namespace;use namespace custom_namespace;public class RoyaleTest_A extends TestProxy { custom_namespace function foo(){if (a) super.setProperty(a, b);}}",
         					IFunctionNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n */\nRoyaleTest_A.prototype[\"http://ns.apache.org/2017/custom/namespace::foo\"] = function() {\n  if (a)\n    RoyaleTest_A.superClass_['http://ns.apache.org/2017/custom/namespace::setProperty'].apply(this, [ a, b] );\n}");
+        assertOut("/**\n * @export\n */\nRoyaleTest_A.prototype.http_$$ns_apache_org$2017$custom$namespace__foo = function() {\n  if (a)\n    RoyaleTest_A.superClass_.http_$$ns_apache_org$2017$custom$namespace__setProperty.apply(this, [ a, b] );\n}");
     }
 
     @Test
@@ -151,7 +178,7 @@
     @Test
     public void testVisitLanguageIdentifierNode_SuperMethodAsVarFunctionReference()
     {
-    	IFileNode node = (IFileNode)getNode("package { public class RoyaleTest_A extends Base { override public function foo() {var f:Function; f = super.foo;} } }\n" +
+    	IFileNode node = (IFileNode)getNode("package { public class RoyaleTest_A extends Base { override public function foo() {var f:Function = null; f = super.foo;} } }\n" +
         		"class Base { public function foo(){} }", IFileNode.class, 0, false);
         IFunctionNode fnode = (IFunctionNode) findFirstDescendantOfType(
                 node, IFunctionNode.class);
@@ -160,7 +187,7 @@
         IClassDefinition def = classnode.getDefinition();
         ((JSRoyaleEmitter)asEmitter).getModel().setCurrentClass(def);
         asBlockWalker.visitFunction(fnode);
-        assertOut("/**\n * @export\n * @override\n */\nRoyaleTest_A.prototype.foo = function() {\n  var /** @type {Function} */ f;\n  f = org.apache.royale.utils.Language.closure(RoyaleTest_A.superClass_.foo, this, 'foo');\n}");
+        assertOut("/**\n * @export\n * @override\n */\nRoyaleTest_A.prototype.foo = function() {\n  var /** @type {Function} */ f = null;\n  f = org.apache.royale.utils.Language.closure(RoyaleTest_A.superClass_.foo, this, 'foo');\n}");
     }
     
     @Test
@@ -243,10 +270,266 @@
     }
 
     @Test
+    public void testVisitBinaryOperatorNode_AssignmentBooleanVarToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool1:Boolean;var bool2:Boolean;bool1 = bool2");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool1 = bool2");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentNumberVarToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var boolean:Boolean;var number:Number;boolean = number");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("boolean = !!(number)");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentBooleanLiteralToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool:Boolean;bool = true");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool = true");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentPositiveNumberLiteralToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool:Boolean;bool = 123.4");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool = true");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentNegativeNumberLiteralToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool:Boolean;bool = -123");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool = true");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentZeroNumberLiteralToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool:Boolean;bool = 0");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool = false");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentDecimalNumberLiteralToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool:Boolean;bool = 0.123");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool = true");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentNullToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool:Boolean;bool = null");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool = false");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentUndefinedToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool:Boolean;bool = undefined");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool = false");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentIntVarToInt()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var integer1:int;var integer2:int;integer1 = integer2");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("integer1 = integer2");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentNumberVarToInt()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var integer:int;var number:Number;integer = number");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("integer = (number) >> 0");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentUintVarToInt()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var integer:int;var unsigned_integer:uint;integer = unsigned_integer");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("integer = (unsigned_integer) >> 0");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentNumberLiteralToInt()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var numToInt:int;numToInt = 123.4");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("numToInt = 123");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentIntLiteralToInt()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var numToInt:int;numToInt = 321");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("numToInt = 321");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentHexIntLiteralToInt()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var numToInt:int;numToInt = 0xabc");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("numToInt = 0xabc");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentNegativeIntLiteralToInt()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var numToInt:int;numToInt = -321");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("numToInt = -321");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentUintVarToUint()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var unsigned_integer1:uint;var unsigned_integer2:uint;unsigned_integer1 = unsigned_integer2");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("unsigned_integer1 = unsigned_integer2");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentNumberVarToUint()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var unsigned_integer:uint;var number:Number;unsigned_integer = number");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("unsigned_integer = (number) >>> 0");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentIntVarToUint()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var unsigned_integer:uint;var integer:int;unsigned_integer = integer");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("unsigned_integer = (integer) >>> 0");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentNumberLiteralToUint()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var numToUint:uint;numToUint = 123.4");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("numToUint = 123");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentNegativeIntLiteralToUint()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var numToUint:uint;numToUint = -123");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("numToUint = 4294967173");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentHexLiteralToUint()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var numToUint:uint;numToUint = 0xabc");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("numToUint = 0xabc");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentStringVarToString()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var var1:String;var var2:String;var1 = var2");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("var1 = var2");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentAnyTypeVarToString()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var var1:String;var var2:*;var1 = var2");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("var1 = org.apache.royale.utils.Language.string(var2)");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentAnyTypeVarToStringSuppressed()
+    {
+        IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
+                "public class B {public var b:String; public var c:Object; /**\n * @royalenoimplicitstringconversion\n */\npublic function d() { b = c; }}",
+                IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
+        JSRoyaleDocEmitter docEmitter = (JSRoyaleDocEmitter)(asBlockWalker.getEmitter().getDocEmitter());
+        IFunctionNode methodNode = (IFunctionNode)(node.getAncestorOfType(IFunctionNode.class));
+        
+        // this adds '/**\n * @royalenoimplicitstringconversion\n * @export\n */' to the output but parses
+        // the asdoc so the emitter will suppress the output
+        docEmitter.emitMethodDoc(methodNode, asBlockWalker.getProject());
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("/**\n * @royalenoimplicitstringconversion\n * @export\n */\nthis.b = this.c");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentXMLChildToString()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var var1:String;var var2:XML;var1 = var2.child");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("var1 = org.apache.royale.utils.Language.string(var2.child('child'))");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentStringLiteralToString()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var var1:String;var1 = \"hi\"");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("var1 = \"hi\"");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentNullToString()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var var1:String;var1 = null");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("var1 = null");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentUndefinedToString()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var var1:String;var1 = undefined");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("var1 = null");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentToStringFunctionCallToString()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var var1:String;var var2:Object;var1 = var2.toString()");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("var1 = var2.toString()");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentDatePropertyToNumber()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var var1:Number;var var2:Date;var1 = var2.month");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("var1 = var2.getMonth()");
+    }
+
+    @Test
     public void testVisitBinaryOperatorNode_setterAssignment()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public function set b(value:int):void {}; public function c() { b = 1; }}",
+                "public class B {public function set b(value:Number):void {}; public function c() { b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.b = 1");
@@ -256,7 +539,7 @@
     public void testVisitBinaryOperatorNode_setterAssignmentWithThis()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public function set b(value:int):void {}; public function c() { this.b = 1; }}",
+                "public class B {public function set b(value:Number):void {}; public function c() { this.b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.b = 1");
@@ -266,7 +549,7 @@
     public void testVisitBinaryOperatorNode_setterAssignmentPrivate()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public function get b():int { return 0; } private function set b(value:int):void {}; public function test() { this.b = 1; }}",
+                "public class B {public function get b():Number { return 0; } private function set b(value:Number):void {}; public function test() { this.b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.b = 1");
@@ -276,7 +559,7 @@
     public void testVisitBinaryOperatorNode_setterAssignmentPrivateWithNamespace()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public function get b():int { return 0; } private function set b(value:int):void {}; public function test() { this.private::b = 1; }}",
+                "public class B {public function get b():Number { return 0; } private function set b(value:Number):void {}; public function test() { this.private::b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.b = 1");
@@ -290,7 +573,7 @@
         // disconnect fileNode from parent
         // set thisclass on emitter to class def
         IFileNode node = (IFileNode) getNode(
-                "public class B { public function c() { this.b = 1; }; public function set b(value:int):void {}}",
+                "public class B { public function c() { this.b = 1; }; public function set b(value:Number):void {}}",
                 IFileNode.class, WRAP_LEVEL_PACKAGE, true);
         IFunctionNode fnode = (IFunctionNode) findFirstDescendantOfType(
                 node, IFunctionNode.class);
@@ -314,7 +597,7 @@
         // disconnect fileNode from parent
         // set thisclass on emitter to class def
         IFileNode node = (IFileNode) getNode(
-                "public class B { public function c() { b = 1; }; public function set b(value:int):void {}}",
+                "public class B { public function c() { b = 1; }; public function set b(value:Number):void {}}",
                 IFileNode.class, WRAP_LEVEL_PACKAGE, true);
         IFunctionNode fnode = (IFunctionNode) findFirstDescendantOfType(
                 node, IFunctionNode.class);
@@ -334,7 +617,7 @@
     public void testVisitBinaryOperatorNode_setterAssignmentOtherInstance()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public function set b(value:int):void {}; public function c(other:B) { other.b = 1; }}",
+                "public class B {public function set b(value:Number):void {}; public function c(other:B) { other.b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("other.b = 1");
@@ -344,7 +627,7 @@
     public void testVisitBinaryOperatorNode_nestedSetterAssignment()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public function set b(value:int):void {}; public function get d():B {}; public function c(other:B) { d.d.b = 1; }}",
+                "public class B {public function set b(value:Number):void {}; public function get d():B {}; public function c(other:B) { d.d.b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.d.d.b = 1");
@@ -354,7 +637,7 @@
     public void testVisitBinaryOperatorNode_nestedSetterAssignmentOtherInstance()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public function set b(value:int):void {}; public function get d():B {}; public function c(other:B) { other.d.b = 1; }}",
+                "public class B {public function set b(value:Number):void {}; public function get d():B {}; public function c(other:B) { other.d.b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("other.d.b = 1");
@@ -364,7 +647,7 @@
     public void testVisitBinaryOperatorNode_setterAssignmentFromGetter()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public function set b(value:int):void {}; public function c() { b = b + 1; }}",
+                "public class B {public function set b(value:Number):void {}; public function c() { b = b + 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.b = this.b + 1");
@@ -374,7 +657,7 @@
     public void testVisitBinaryOperatorNode_setterAssignmentFromGetterMaskedByLocal()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public function set b(value:int):void {}; public function c() { var b:int; b = b + 1; }}",
+                "public class B {public function set b(value:Number):void {}; public function c() { var b:Number; b = b + 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("b = b + 1");
@@ -384,7 +667,7 @@
     public void testVisitBinaryOperatorNode_setterAssignmentFromGetterMaskedByParam()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public function set b(value:int):void {}; public function c(b:int) { b = b + 1; }}",
+                "public class B {public function set b(value:Number):void {}; public function c(b:Number) { b = b + 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("b = b + 1");
@@ -394,7 +677,7 @@
     public void testVisitBinaryOperatorNode_setterAssignmentFromInternalVar()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {var b:int; public function c() { b = b + 1; }}",
+                "public class B {var b:Number; public function c() { b = b + 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.b = this.b + 1");
@@ -404,7 +687,7 @@
     public void testVisitBinaryOperatorNode_staticSetterAssignmentFromInternalVar()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {static var b:int; public function c() { b = b + 1; }}",
+                "public class B {static var b:Number; public function c() { b = b + 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("B.b = B.b + 1");
@@ -414,7 +697,7 @@
     public void testVisitBinaryOperatorNode_bindableAssignment()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {[Bindable] public var b:int; public function c() { b = 1; }}",
+                "public class B {[Bindable] public var b:Number; public function c() { b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.b = 1");
@@ -424,7 +707,7 @@
     public void testVisitBinaryOperatorNode_bindableAssignmentWithThis()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {[Bindable] public var b:int; public function c() { this.b = 1; }}",
+                "public class B {[Bindable] public var b:Number; public function c() { this.b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.b = 1");
@@ -434,7 +717,7 @@
     public void testVisitBinaryOperatorNode_bindableAssignmentOtherInstance()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {[Bindable] public var b:int; public function c(other:B) { other.b = 1; }}",
+                "public class B {[Bindable] public var b:Number; public function c(other:B) { other.b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("other.b = 1");
@@ -444,7 +727,7 @@
     public void testVisitBinaryOperatorNode_bindableSetterAssignment()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {[Bindable] public var b:int; [Bindable] public var d:B; public function c(other:B) { d.d.b = 1; }}",
+                "public class B {[Bindable] public var b:Number; [Bindable] public var d:B; public function c(other:B) { d.d.b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.d.d.b = 1");
@@ -454,7 +737,7 @@
     public void testVisitBinaryOperatorNode_bindableSetterAssignmentOtherInstance()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {[Bindable] public var b:int; [Bindable] public var d:B; public function c(other:B) { other.d.b = 1; }}",
+                "public class B {[Bindable] public var b:Number; [Bindable] public var d:B; public function c(other:B) { other.d.b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("other.d.b = 1");
@@ -464,7 +747,7 @@
     public void testVisitBinaryOperatorNode_bindableAssignmentFromGetter()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {[Bindable] public var b:int; public function c() { b = b + 1; }}",
+                "public class B {[Bindable] public var b:Number; public function c() { b = b + 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.b = this.b + 1");
@@ -474,7 +757,7 @@
     public void testVisitBinaryOperatorNode_bindableAssignmentFromGetterMaskedByLocal()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {[Bindable] public var b:int; public function c() { var b:int; b = b + 1; }}",
+                "public class B {[Bindable] public var b:Number; public function c() { var b:Number; b = b + 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("b = b + 1");
@@ -484,7 +767,7 @@
     public void testVisitBinaryOperatorNode_bindableAssignmentFromGetterMaskedByParam()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {[Bindable] public var b:int; public function c(b:int) { b = b + 1; }}",
+                "public class B {[Bindable] public var b:Number; public function c(b:Number) { b = b + 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("b = b + 1");
@@ -494,7 +777,7 @@
     public void testVisitBinaryOperatorNode_varAssignment()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public var b:int; public function c() { b = 1; }}",
+                "public class B {public var b:Number; public function c() { b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.b = 1");
@@ -504,7 +787,7 @@
     public void testVisitBinaryOperatorNode_varAssignmentWithThis()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public var b:int; public function c() { this.b = 1; }}",
+                "public class B {public var b:Number; public function c() { this.b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.b = 1");
@@ -514,7 +797,7 @@
     public void testVisitBinaryOperatorNode_varAssignmentOtherInstance()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public var b:int; public function c(other:B) { other.b = 1; }}",
+                "public class B {public var b:Number; public function c(other:B) { other.b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("other.b = 1");
@@ -524,7 +807,7 @@
     public void testVisitBinaryOperatorNode_varSetterAssignment()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {[Bindable] public var b:int; public var d:B; public function c(other:B) { d.d.b = 1; }}",
+                "public class B {[Bindable] public var b:Number; public var d:B; public function c(other:B) { d.d.b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.d.d.b = 1");
@@ -534,7 +817,7 @@
     public void testVisitBinaryOperatorNode_varVarAssignment()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public var b:int; public var d:B; public function c(other:B) { d.d.b = 1; }}",
+                "public class B {public var b:Number; public var d:B; public function c(other:B) { d.d.b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.d.d.b = 1");
@@ -544,7 +827,7 @@
     public void testVisitBinaryOperatorNode_varSetterAssignmentOtherInstance()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {[Bindable] public var b:int; public var d:B; public function c(other:B) { other.d.b = 1; }}",
+                "public class B {[Bindable] public var b:Number; public var d:B; public function c(other:B) { other.d.b = 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("other.d.b = 1");
@@ -554,7 +837,7 @@
     public void testVisitBinaryOperatorNode_varAssignmentFromVar()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public var b:int; public function c() { b = b + 1; }}",
+                "public class B {public var b:Number; public function c() { b = b + 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("this.b = this.b + 1");
@@ -564,7 +847,7 @@
     public void testVisitBinaryOperatorNode_varAssignmentFromVarMaskedByLocal()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public var b:int; public function c() { var b:int; b = b + 1; }}",
+                "public class B {public var b:Number; public function c() { var b:Number; b = b + 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("b = b + 1");
@@ -574,7 +857,7 @@
     public void testVisitBinaryOperatorNode_varAssignmentFromVarMaskedByParam()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public var b:int; public function c(b:int) { b = b + 1; }}",
+                "public class B {public var b:Number; public function c(b:Number) { b = b + 1; }}",
                 IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitBinaryOperator(node);
         assertOut("b = b + 1");
@@ -584,7 +867,7 @@
     public void testVisitBinaryOperatorNode_staticSetterAssignment()
     {
         IFunctionNode node = (IFunctionNode) getNode(
-                "public class B {public function c() { b = 1; }; public static function set b(value:int):void {}}",
+                "public class B {public function c() { b = 1; }; public static function set b(value:Number):void {}}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         IBinaryOperatorNode bnode = (IBinaryOperatorNode) findFirstDescendantOfType(
                 node, IBinaryOperatorNode.class);
@@ -596,7 +879,7 @@
     public void testVisitBinaryOperatorNode_staticSetterAssignmentWithPath()
     {
         IFunctionNode node = (IFunctionNode) getNode(
-                "public class B {public function c() { foo.bar.B.b = 1; }; public static function set b(value:int):void {}}",
+                "public class B {public function c() { foo.bar.B.b = 1; }; public static function set b(value:Number):void {}}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         IBinaryOperatorNode bnode = (IBinaryOperatorNode) findFirstDescendantOfType(
                 node, IBinaryOperatorNode.class);
@@ -608,7 +891,7 @@
     public void testVisitBinaryOperatorNode_staticSetterAssignmentOtherInstance()
     {
         IFunctionNode node = (IFunctionNode) getNode(
-                "public class B {public function c() { d.b = 1; }; public function set b(value:int):void {}; public static function get d():B {}}",
+                "public class B {public function c() { d.b = 1; }; public function set b(value:Number):void {}; public static function get d():B {}}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         IBinaryOperatorNode bnode = (IBinaryOperatorNode) findFirstDescendantOfType(
                 node, IBinaryOperatorNode.class);
@@ -624,7 +907,7 @@
         // disconnect fileNode from parent
         // set thisclass on emitter to class def
         IFileNode node = (IFileNode) getNode(
-                "public class B {public function c() { d.b = 1; }; public function set b(value:int):void {}; public static function get d():B {}}",
+                "public class B {public function c() { d.b = 1; }; public function set b(value:Number):void {}; public static function get d():B {}}",
                 IFileNode.class, WRAP_LEVEL_PACKAGE, true);
         IFunctionNode fnode = (IFunctionNode) findFirstDescendantOfType(
                 node, IFunctionNode.class);
@@ -644,7 +927,7 @@
     public void testVisitBinaryOperatorNode_staticSetterAssignmentFromGetter()
     {
         IFunctionNode node = (IFunctionNode) getNode(
-                "public class B {public function c() { b = b + 1; }; public static function set b(value:int):void {}; public static function get b():int {}}",
+                "public class B {public function c() { b = b + 1; }; public static function set b(value:Number):void {}; public static function get b():Number {}}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         IBinaryOperatorNode bnode = (IBinaryOperatorNode) findFirstDescendantOfType(
                 node, IBinaryOperatorNode.class);
@@ -656,7 +939,7 @@
     public void testVisitBinaryOperatorNode_staticSetterAssignmentFromGetterMaskedByLocal()
     {
         IFunctionNode node = (IFunctionNode) getNode(
-                "public class B {public function c() { var b:int; b = b + 1; }; public static function set b(value:int):void {}; public static function get b():int {}}",
+                "public class B {public function c() { var b:Number; b = b + 1; }; public static function set b(value:Number):void {}; public static function get b():Number {}}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         IBinaryOperatorNode bnode = (IBinaryOperatorNode) findFirstDescendantOfType(
                 node, IBinaryOperatorNode.class);
@@ -668,7 +951,7 @@
     public void testVisitBinaryOperatorNode_staticSetterAssignmentFromGetterMaskedByParam()
     {
         IFunctionNode node = (IFunctionNode) getNode(
-                "public class B {public function c(b:int) { b = b + 1; }; public static function set b(value:int):void {}; public static function get b():int {}}",
+                "public class B {public function c(b:Number) { b = b + 1; }; public static function set b(value:Number):void {}; public static function get b():Number {}}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         IBinaryOperatorNode bnode = (IBinaryOperatorNode) findFirstDescendantOfType(
                 node, IBinaryOperatorNode.class);
@@ -711,32 +994,6 @@
     }
 
     @Test
-    public void testVisitBinaryOperatorNode_StringVarAssignmentFromObject()
-    {
-        IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public var b:String; public var c:Object; public function d() { b = c; }}",
-                IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
-        asBlockWalker.visitBinaryOperator(node);
-        assertOut("this.b = org.apache.royale.utils.Language.string(this.c)");
-    }
-
-    @Test
-    public void testVisitBinaryOperatorNode_StringVarAssignmentFromObjectSupressed()
-    {
-        IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public var b:String; public var c:Object; /**\n * @royalenoimplicitstringconversion\n */\npublic function d() { b = c; }}",
-                IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
-        JSRoyaleDocEmitter docEmitter = (JSRoyaleDocEmitter)(asBlockWalker.getEmitter().getDocEmitter());
-        IFunctionNode methodNode = (IFunctionNode)(node.getAncestorOfType(IFunctionNode.class));
-        
-        // this adds '/**\n * @royalenoimplicitstringconversion\n * @export\n */' to the output but parses
-        // the asdoc so the emitter will suppress the output
-        docEmitter.emitMethodDoc(methodNode, asBlockWalker.getProject());
-        asBlockWalker.visitBinaryOperator(node);
-        assertOut("/**\n * @royalenoimplicitstringconversion\n * @export\n */\nthis.b = this.c");
-    }
-
-    @Test
     public void testVisitBinaryOperatorNode_StringVarCompareWithObject()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
@@ -767,16 +1024,6 @@
     }
 
     @Test
-    public void testVisitBinaryOperatorNode_StringAssignFromStarToString()
-    {
-        IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
-                "public class B {public var b:String; public var c:*; public function d() { b = c.toString(); }}",
-                IBinaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
-        asBlockWalker.visitBinaryOperator(node);
-        assertOut("this.b = this.c.toString()");
-    }
-
-    @Test
     public void testVisitBinaryOperatorNode_NumberPlusString()
     {
         IBinaryOperatorNode node = (IBinaryOperatorNode) getNode(
@@ -897,13 +1144,43 @@
     }
     
     @Test
+    public void testCustomNamespaceMethodAsParameter()
+    {
+        IFunctionNode node = (IFunctionNode) getNode(
+                "import custom.custom_namespace; use namespace custom_namespace;public class B {custom_namespace function b() { function c(f:Function):void {}; c(b); }}",
+                IFunctionNode.class, WRAP_LEVEL_PACKAGE);
+        asBlockWalker.visitFunction(node);
+        assertOut("/**\n * @export\n */\nB.prototype.http_$$ns_apache_org$2017$custom$namespace__b = function() {\n  var self = this;\n  function c(f) {\n  };\n  c(org.apache.royale.utils.Language.closure(this.http_$$ns_apache_org$2017$custom$namespace__b, this, 'http://ns.apache.org/2017/custom/namespace::b'));\n}");
+    }
+    
+    @Test
+    public void testCustomNamespaceMethodAsParameterWithoutUse()
+    {
+        IFunctionNode node = (IFunctionNode) getNode(
+                "import custom.custom_namespace;public class B {custom_namespace function b() { function c(f:Function):void {}; c(custom_namespace::b); }}",
+                IFunctionNode.class, WRAP_LEVEL_PACKAGE);
+        asBlockWalker.visitFunction(node);
+        assertOut("/**\n * @export\n */\nB.prototype.http_$$ns_apache_org$2017$custom$namespace__b = function() {\n  var self = this;\n  function c(f) {\n  };\n  c(org.apache.royale.utils.Language.closure(this.http_$$ns_apache_org$2017$custom$namespace__b, this, 'http://ns.apache.org/2017/custom/namespace::b'));\n}");
+    }
+    
+    @Test
     public void testCustomNamespaceMethodAsVariable()
     {
         IFunctionNode node = (IFunctionNode) getNode(
                 "import custom.custom_namespace; use namespace custom_namespace;public class B {custom_namespace function b() { function c(f:Function):void {}; var f:Function = b; c(f); }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n */\nB.prototype[\"http://ns.apache.org/2017/custom/namespace::b\"] = function() {\n  var self = this;\n  function c(f) {\n  };\n  var /** @type {Function} */ f = org.apache.royale.utils.Language.closure(this[\"http://ns.apache.org/2017/custom/namespace::b\"], this, 'http://ns.apache.org/2017/custom/namespace::b');\n  c(f);\n}");
+        assertOut("/**\n * @export\n */\nB.prototype.http_$$ns_apache_org$2017$custom$namespace__b = function() {\n  var self = this;\n  function c(f) {\n  };\n  var /** @type {Function} */ f = org.apache.royale.utils.Language.closure(this.http_$$ns_apache_org$2017$custom$namespace__b, this, 'http://ns.apache.org/2017/custom/namespace::b');\n  c(f);\n}");
+    }
+    
+    @Test
+    public void testCustomNamespaceMethodAsVariableWithoutUse()
+    {
+        IFunctionNode node = (IFunctionNode) getNode(
+                "import custom.custom_namespace;;public class B {custom_namespace function b() { function c(f:Function):void {}; var f:Function = this.custom_namespace::b; c(f); }}",
+                IFunctionNode.class, WRAP_LEVEL_PACKAGE);
+        asBlockWalker.visitFunction(node);
+        assertOut("/**\n * @export\n */\nB.prototype.http_$$ns_apache_org$2017$custom$namespace__b = function() {\n  var self = this;\n  function c(f) {\n  };\n  var /** @type {Function} */ f = org.apache.royale.utils.Language.closure(this[new QName(custom.custom_namespace, 'b').objectAccessFormat()], this, 'http://ns.apache.org/2017/custom/namespace::b');\n  c(f);\n}");
     }
     
     @Test
@@ -913,7 +1190,7 @@
                 "import custom.custom_namespace; use namespace custom_namespace;public class B {custom_namespace function b():int { return this.b(); }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @return {number}\n */\nB.prototype[\"http://ns.apache.org/2017/custom/namespace::b\"] = function() {\n  return this[\"http://ns.apache.org/2017/custom/namespace::b\"]();\n}");
+        assertOut("/**\n * @export\n * @return {number}\n */\nB.prototype.http_$$ns_apache_org$2017$custom$namespace__b = function() {\n  return this.http_$$ns_apache_org$2017$custom$namespace__b();\n}");
     }
     
     @Test
@@ -940,20 +1217,20 @@
     public void testMethodAsAssign()
     {
         IFunctionNode node = (IFunctionNode) getNode(
-                "public class B {public function b() { function c(f:Function):void {}; var f:Function; f = b; c(f); }}",
+                "public class B {public function b() { function c(f:Function):void {}; var f:Function = null; f = b; c(f); }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  var self = this;\n  function c(f) {\n  };\n  var /** @type {Function} */ f;\n  f = org.apache.royale.utils.Language.closure(this.b, this, 'b');\n  c(f);\n}");
+        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  var self = this;\n  function c(f) {\n  };\n  var /** @type {Function} */ f = null;\n  f = org.apache.royale.utils.Language.closure(this.b, this, 'b');\n  c(f);\n}");
     }
     
     @Test
     public void testStaticMethodAsAssign()
     {
         IFunctionNode node = (IFunctionNode) getNode(
-                "public class B {static public function b() { function c(f:Function):void {}; var f:Function; f = b; c(f); }}",
+                "public class B {static public function b() { function c(f:Function):void {}; var f:Function = null; f = b; c(f); }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nfoo.bar.B.b = function() {\n  function c(f) {\n  };\n  var /** @type {Function} */ f;\n  f = foo.bar.B.b;\n  c(f);\n}");
+        assertOut("/**\n * @export\n */\nfoo.bar.B.b = function() {\n  function c(f) {\n  };\n  var /** @type {Function} */ f = null;\n  f = foo.bar.B.b;\n  c(f);\n}");
     }
     
     @Test
@@ -963,7 +1240,7 @@
                 "public class B {public function b() { function c(f:Function):void {}; var f:Array = [b]; c(f[0]); }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  var self = this;\n  function c(f) {\n  };\n  var /** @type {Array} */ f = [org.apache.royale.utils.Language.closure(this.b, this, 'b')];\n  c(f[0]);\n}");
+        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  var self = this;\n  function c(f) {\n  };\n  var /** @type {Array} */ f = [org.apache.royale.utils.Language.closure(this.b, this, 'b')];\n  c(/* implicit cast */ org.apache.royale.utils.Language.as(f[0], Function, true));\n}");
     }
     
     @Test
@@ -1000,22 +1277,22 @@
     public void testNativeGetter()
     {
         IFunctionNode node = (IFunctionNode) getNode(
-                "public class B {public function b():int { var s:String; return s.length; }}",
+                "public class B {public function b():Number { var s:String = null; return s.length; }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         asBlockWalker.visitFunction(node);
         // String.length is a getter but is a property in JS, so don't generate set_length() call.
-        assertOut("/**\n * @export\n * @return {number}\n */\nfoo.bar.B.prototype.b = function() {\n  var /** @type {string} */ s;\n  return s.length;\n}");
+        assertOut("/**\n * @export\n * @return {number}\n */\nfoo.bar.B.prototype.b = function() {\n  var /** @type {string} */ s = null;\n  return s.length;\n}");
     }
 
     @Test
     public void testNativeVectorGetter()
     {
         IFunctionNode node = (IFunctionNode) getNode(
-                "public class B {public function b():int { var a:Vector.<String>; return a.length; }}",
+                "public class B {public function b():Number { var a:Vector.<String> = null; return a.length; }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         asBlockWalker.visitFunction(node);
         // String.length is a getter but is a property in JS, so don't generate set_length() call.
-        assertOut("/**\n * @export\n * @return {number}\n */\nfoo.bar.B.prototype.b = function() {\n  var /** @type {Array} */ a;\n  return a.length;\n}");
+        assertOut("/**\n * @export\n * @return {number}\n */\nfoo.bar.B.prototype.b = function() {\n  var /** @type {Array.<string>} */ a = null;\n  return a.length;\n}");
     }
 
     //----------------------------------
@@ -1057,6 +1334,16 @@
     }
 
     @Test
+    public void testFunctionCallCustomNamespace()
+    {
+        IFunctionNode node = (IFunctionNode) getNode(
+                "import custom.custom_namespace; public class B {custom_namespace function b() { custom_namespace::b(); }}",
+                IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
+        asBlockWalker.visitFunction(node);
+        assertOut("/**\n * @export\n */\nfoo.bar.B.prototype.http_$$ns_apache_org$2017$custom$namespace__b = function() {\n  this.http_$$ns_apache_org$2017$custom$namespace__b();\n}");
+    }
+
+    @Test
     public void testFunctionMemberFullyQualified()
     {
         IFunctionNode node = (IFunctionNode) getNode(
@@ -1069,9 +1356,9 @@
     @Test
     public void testComplexBooleanExpression()
     {
-        IFunctionNode node = getMethod("function foo(b:Boolean):Boolean {var c:String; var d:String; if (!(b ? c : d)) { return b;}}");
+        IFunctionNode node = getMethod("function foo(b:Boolean):Boolean {var c:String = null; var d:String = null; if (!(b ? c : d)) { return b;}}");
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @param {boolean} b\n * @return {boolean}\n */\nRoyaleTest_A.prototype.foo = function(b) {\n  var /** @type {string} */ c;\n  var /** @type {string} */ d;\n  if (!(b ? c : d)) {\n    return b;\n  }\n}");
+        assertOut("/**\n * @export\n * @param {boolean} b\n * @return {boolean}\n */\nRoyaleTest_A.prototype.foo = function(b) {\n  var /** @type {string} */ c = null;\n  var /** @type {string} */ d = null;\n  if (!(b ? c : d)) {\n    return b;\n  }\n}");
     }
 
     @Override
@@ -1082,11 +1369,10 @@
                 IFunctionNode.class);
         asBlockWalker.visitFunction(node);
         assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n" +
-        		  "  var self = this;\n" +
-        		  "  var /** @type {Function} */ __localFn0__ = function() {\n" +
-        		  "  }\n" +
-        		  "  var /** @type {*} */ a = __localFn0__;\n" +
-        		  "}");
+        	  "  var self = this;\n" +
+        	  "  var /** @type {*} */ a = function() {\n" +
+        	  "  };\n" +
+        	  "}");
     }
 
     @Override
@@ -1099,11 +1385,10 @@
         asBlockWalker.visitFunction(node);
         assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n" +
       		  "  var self = this;\n" +
-      		  "  var /** @type {Function} */ __localFn0__ = function(foo, bar) {\n" +
+      		  "  var /** @type {Object} */ a = function(foo, bar) {\n" +
       		  "    bar = typeof bar !== 'undefined' ? bar : 'goo';\n" +
       		  "    return -1;\n" +
-      		  "  }\n" +
-      		  "  var /** @type {Object} */ a = __localFn0__;\n" +
+      		  "  };\n" +
       		  "}");
     }
 
@@ -1117,12 +1402,41 @@
         asBlockWalker.visitFunction(node);
         assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n" +
       		  "  var self = this;\n" +
-      		  "  var /** @type {Function} */ __localFn0__ = function(event) {\n" +
+      		  "  addListener('foo', function(event) {\n" +
       		  "    doit();\n" +
-      		  "  }\n" +
-      		  "  addListener('foo', __localFn0__);\n" +
+      		  "  });\n" +
       		  "}");
     }
+    
+    @Override
+    @Test
+    public void testVisitLocalNamedFunction()
+    {
+        IFunctionNode node = (IFunctionNode) getNode("function a() {};", IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n" +
+                  "  var self = this;\n" +
+                  "  function a() {\n" +
+                  "  };\n" +
+                  "  \n" +
+                  "}");
+    }
+    
+    @Override
+    @Test
+    public void testVisitLocalNamedFunctionWithParamsReturn()
+    {
+        IFunctionNode node = (IFunctionNode) getNode("function a(foo:int, bar:String = 'goo'):int{return -1;};", IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n" +
+                  "  var self = this;\n" +
+                  "  function a(foo, bar) {\n" +
+                  "    bar = typeof bar !== 'undefined' ? bar : 'goo';\n" +
+                  "    return -1;\n" +
+                  "  };\n" +
+                  "  \n" +
+                  "}");
+    }
 
     @Test
     public void testES5StrictAnonymousFunctions()
@@ -1133,9 +1447,8 @@
         asBlockWalker.visitFunction(node);
         assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n" +
         		  "  var self = this;\n" +
-        		  "  var /** @type {Function} */ __localFn0__ = function(foo) {\n    foo.bar = 10;\n  }\n" +
         		  "  var /** @type {Object} */ a = {};\n" +
-        		  "  var /** @type {Function} */ b = __localFn0__;\n" +
+        		  "  var /** @type {Function} */ b = function(foo) {\n    foo.bar = 10;\n  };\n" +
         		  "  var /** @type {Object} */ c = b(a);\n}");
     }
     
@@ -1154,6 +1467,22 @@
     }
     
     @Test
+    public void testES5StrictNamedLocalFunctionsAsParameter()
+    {
+        IFunctionNode node = (IFunctionNode) getNode(
+                "public function foo() { var a:Array = []; a.filter(function isEven(element: int, index: int, arr: Array) : Boolean {\n" + 
+                "  return element % 2 == 0;\n" + 
+                "});}",
+                IFunctionNode.class, WRAP_LEVEL_CLASS);
+        asBlockWalker.visitFunction(node);
+        assertOut("/**\n * @export\n */\n" + 
+      		  "RoyaleTest_A.prototype.foo = function() {\n" +
+      		  "  var self = this;\n" +
+      		  "  function isEven(element, index, arr) {\n    return element % 2 == 0;\n  };\n  var /** @type {Array} */ a = [];\n"
+      		  + "  a.filter(isEven);\n}");
+    }
+    
+    @Test
     public void testParametersInInnerFunctions()
     {
         IFunctionNode node = (IFunctionNode) getNode(
@@ -1192,10 +1521,10 @@
     public void testVisitAs2()
     {
         IFunctionNode node = (IFunctionNode) getNode(
-                "public class B {public function b(o:Object):int { var a:B; a = o as B; }}",
+                "public class B {public function b(o:Object):int { var a:B = null; a = o as B; }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n * @param {Object} o\n * @return {number}\n */\nfoo.bar.B.prototype.b = function(o) {\n  var /** @type {foo.bar.B} */ a;\n  a = org.apache.royale.utils.Language.as(o, foo.bar.B);\n}");
+        assertOut("/**\n * @export\n * @param {Object} o\n * @return {number}\n */\nfoo.bar.B.prototype.b = function(o) {\n  var /** @type {foo.bar.B} */ a = null;\n  a = org.apache.royale.utils.Language.as(o, foo.bar.B);\n}");
     }
 
     @Test
@@ -1203,7 +1532,7 @@
     {
         IBinaryOperatorNode node = getBinaryNode("a as int");
         asBlockWalker.visitBinaryOperator(node);
-        assertOut("org.apache.royale.utils.Language.as(a, Number)");
+        assertOut("org.apache.royale.utils.Language.as(a, org.apache.royale.utils.Language.synthType('int'))");
     }
 
     @Test
@@ -1211,27 +1540,92 @@
     {
         IBinaryOperatorNode node = getBinaryNode("a as uint");
         asBlockWalker.visitBinaryOperator(node);
-        assertOut("org.apache.royale.utils.Language.as(a, Number)");
+        assertOut("org.apache.royale.utils.Language.as(a, org.apache.royale.utils.Language.synthType('uint'))");
     }
 
     @Test
     public void testVisitAsMemberVariable()
     {
         IFunctionNode node = (IFunctionNode) getNode(
-                "public class B {private var memberVar:Class; public function b(o:Object):int { var a:B; a = o as memberVar; }}",
+                "public class B {private var memberVar:Class; public function b(o:Object):int { var a:B = null; a = o as memberVar; }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n * @param {Object} o\n * @return {number}\n */\nfoo.bar.B.prototype.b = function(o) {\n  var /** @type {foo.bar.B} */ a;\n  a = org.apache.royale.utils.Language.as(o, this.memberVar);\n}");
+        assertOut("/**\n * @export\n * @param {Object} o\n * @return {number}\n */\nfoo.bar.B.prototype.b = function(o) {\n  var /** @type {foo.bar.B} */ a = null;\n  a = /* implicit cast */ org.apache.royale.utils.Language.as(org.apache.royale.utils.Language.as(o, this.memberVar), foo.bar.B, true);\n}");
     }
+    
+     @Test
+     public void testVisitAsMemberVariableSuppressComplexImplicitCoercionA()
+     {
+         IFunctionNode node = (IFunctionNode) getNode(
+                 "public class B {private var memberVar:Class; /**\n * @royalesuppresscompleximplicitcoercion\n */\n public function b(o:Object):int { var a:B = null; a = o as memberVar; }}",
+                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
+         asBlockWalker.visitFunction(node);
+         assertOut("/**\n * @royalesuppresscompleximplicitcoercion\n * @export\n * @param {Object} o\n * @return {number}\n */\nfoo.bar.B.prototype.b = function(o) {\n  var /** @type {foo.bar.B} */ a = null;\n  a = org.apache.royale.utils.Language.as(o, this.memberVar);\n}");
+     }
+    
+     @Test
+     public void testVisitAsMemberVariableSuppressComplexImplicitCoercionB()
+     {
+         IFunctionNode node = (IFunctionNode) getNode(
+                 "public class B {private var memberVar:Class; /**\n * @royalesuppresscompleximplicitcoercion true\n */\n public function b(o:Object):int { var a:B = null; a = o as memberVar; }}",
+                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
+         asBlockWalker.visitFunction(node);
+         assertOut("/**\n * @royalesuppresscompleximplicitcoercion true\n * @export\n * @param {Object} o\n * @return {number}\n */\nfoo.bar.B.prototype.b = function(o) {\n  var /** @type {foo.bar.B} */ a = null;\n  a = org.apache.royale.utils.Language.as(o, this.memberVar);\n}");
+     }
+    
+     @Test
+     public void testVisitAsMemberVariableSuppressComplexImplicitCoercionC()
+     {
+         IFunctionNode node = (IFunctionNode) getNode(
+                 "public class B {private var memberVar:Class; /**\n * @royalesuppresscompleximplicitcoercion foo.bar.B\n */\n public function b(o:Object):int { var a:B = null; a = o as memberVar; }}",
+                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
+         asBlockWalker.visitFunction(node);
+         assertOut("/**\n * @royalesuppresscompleximplicitcoercion foo.bar.B\n * @export\n * @param {Object} o\n * @return {number}\n */\nfoo.bar.B.prototype.b = function(o) {\n  var /** @type {foo.bar.B} */ a = null;\n  a = org.apache.royale.utils.Language.as(o, this.memberVar);\n}");
+     }
+    
+    
+     @Test
+     public void testVisitAsMemberVariableSuppressComplexImplicitCoercionD()
+     {
+         //using config level setting to suppress the output by default
+         try{
+             project.config.setJsComplexImplicitCoercions(null,false);
+         } catch (ConfigurationException e) {
+             e.printStackTrace();
+         }
+         
+         IFunctionNode node = (IFunctionNode) getNode(
+                 "public class B {private var memberVar:Class; public function b(o:Object):int { var a:B = null; a = o as memberVar; }}",
+                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
+         asBlockWalker.visitFunction(node);
+         assertOut("/**\n * @export\n * @param {Object} o\n * @return {number}\n */\nfoo.bar.B.prototype.b = function(o) {\n  var /** @type {foo.bar.B} */ a = null;\n  a = org.apache.royale.utils.Language.as(o, this.memberVar);\n}");
+     }
+    
+     @Test
+     public void testVisitAsMemberVariableSuppressComplexImplicitCoercionE()
+     {
+         //using config level setting to suppress the output by default
+         try{
+             project.config.setJsComplexImplicitCoercions(null,false);
+         } catch (ConfigurationException e) {
+             e.printStackTrace();
+         }
+         //reverse the config level suppression (with 'false')
+         IFunctionNode node = (IFunctionNode) getNode(
+                 "public class B {private var memberVar:Class; /**\n * @royalesuppresscompleximplicitcoercion false\n */\n public function b(o:Object):int { var a:B = null; a = o as memberVar; }}",
+                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
+         asBlockWalker.visitFunction(node);
+         assertOut("/**\n * @royalesuppresscompleximplicitcoercion false\n * @export\n * @param {Object} o\n * @return {number}\n */\nfoo.bar.B.prototype.b = function(o) {\n  var /** @type {foo.bar.B} */ a = null;\n  a = /* implicit cast */ org.apache.royale.utils.Language.as(org.apache.royale.utils.Language.as(o, this.memberVar), foo.bar.B, true);\n}");
+     }
 
     @Test
     public void testVisitJSDoc()
     {
         IFunctionNode node = (IFunctionNode) getNode(
-                "public class LinkableString {public function b(o:Object):int { var a:LinkableString; a = o as LinkableString; }}",
+                "public class LinkableString {public function b(o:Object):int { var a:LinkableString = null; a = o as LinkableString; }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n * @param {Object} o\n * @return {number}\n */\nfoo.bar.LinkableString.prototype.b = function(o) {\n  var /** @type {foo.bar.LinkableString} */ a;\n  a = org.apache.royale.utils.Language.as(o, foo.bar.LinkableString);\n}");
+        assertOut("/**\n * @export\n * @param {Object} o\n * @return {number}\n */\nfoo.bar.LinkableString.prototype.b = function(o) {\n  var /** @type {foo.bar.LinkableString} */ a = null;\n  a = org.apache.royale.utils.Language.as(o, foo.bar.LinkableString);\n}");
     }
 
     @Override
@@ -1356,7 +1750,7 @@
     @Test
     public void testVisitCallFunctionReturnedFromFunction()
     {
-        IFunctionCallNode node = (IFunctionCallNode) getNode("function foo(a:String, b:String):Function { return null }; return foo(3, 4)(1, 2);", 
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function foo(a:int, b:int):Function { return null }; return foo(3, 4)(1, 2);", 
         							IFunctionCallNode.class);
         asBlockWalker.visitFunctionCall(node);
         assertOut("foo(3, 4)(1, 2)");
@@ -1380,6 +1774,350 @@
         assertOut("new Fn(\"a\", \"b\", \"return a + b;\")(1, 2)");
     }
 
+    @Test
+    public void testVisitReturnBoolean()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return true; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return true");
+    }
+
+    @Test
+    public void testVisitReturnBooleanWithBooleanLiteral()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return true; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return true");
+    }
+
+    @Test
+    public void testVisitReturnBooleanWithPositiveNumberLiteral()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return 123.4; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return true");
+    }
+
+    @Test
+    public void testVisitReturnBooleanWithNegativeNumberLiteral()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return -123; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return true");
+    }
+
+    @Test
+    public void testVisitReturnBooleanWithZeroLiteral()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return 0; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return false");
+    }
+
+    @Test
+    public void testVisitReturnBooleanWithDecimalLiteral()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return 0.01; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return true");
+    }
+
+    @Test
+    public void testVisitReturnBooleanWithNull()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return null; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return false");
+    }
+
+    @Test
+    public void testVisitReturnBooleanWithUndefined()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return undefined; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return false");
+    }
+
+    @Test
+    public void testVisitReturnIntWithIntLiteral()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():int { return 123; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return 123");
+    }
+
+    @Test
+    public void testVisitReturnIntWithHexIntLiteral()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():int { return 0xabc; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return 0xabc");
+    }
+
+    @Test
+    public void testVisitReturnIntWithDecimalValue()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():int { return -123.4; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return -123");
+    }
+
+    @Test
+    public void testVisitReturnUintWithDecimalValue()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():uint { return 123.4; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return 123");
+    }
+
+    @Test
+    public void testVisitReturnUintWithNegativeValue()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():uint { return -123; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return 4294967173");
+    }
+
+    @Test
+    public void testVisitReturnUintWithHexLiteral()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():uint { return 0xabc; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return 0xabc");
+    }
+
+    @Test
+    public void testVisitReturnStringWithLiteral()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():String { return \"hi\"; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return \"hi\"");
+    }
+
+    @Test
+    public void testVisitReturnStringWithNull()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():String { return null; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return null");
+    }
+
+    @Test
+    public void testVisitReturnStringWithUndefined()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():String { return undefined; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return null");
+    }
+
+    @Test
+    public void testVisitReturnStringWithStringVar()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():String { var a:String; return a; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return a");
+    }
+
+    @Test
+    public void testVisitReturnStringWithAnyTypeVar()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():String { var a:*; return a; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return org.apache.royale.utils.Language.string(a)");
+    }
+
+    @Test
+    public void testVisitReturnStringWithToStringFunctionCall()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():String { var a:Object; return a.toString(); }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return a.toString()");
+    }
+
+    @Test
+    public void testVisitReturnStringWithXMLChild()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():String { var a:XML; return a.child; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return org.apache.royale.utils.Language.string(a.child('child'))");
+    }
+
+    @Test
+    public void testVisitReturnNumberWithDateProperty()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Number { var a:Date; return a.month; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return a.getMonth()");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithIntParameterHex()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:int):void {}; a(0xabc)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(0xabc)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithIntParameterNegative()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:int):void {}; a(-123)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(-123)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithIntParameterDecimal()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:int):void {}; a(123.4)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(123)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithUintParameterHex()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:uint):void {}; a(0xabc)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(0xabc)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithUintParameterNegative()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:uint):void {}; a(-123)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(4294967173)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithUintParameterDecimal()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:uint):void {}; a(123.4)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(123)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithBooleanParameterBoolean()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:Boolean):void {}; a(false)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(false)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithBooleanParameterPositiveNumberLiteral()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:Boolean):void {}; a(123.4)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(true)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithBooleanParameterNegativeNumberLiteral()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:Boolean):void {}; a(-123)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(true)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithBooleanParameterZeroNumberLiteral()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:Boolean):void {}; a(0.0)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(false)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithBooleanParameterLessThanOneNumberLiteral()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:Boolean):void {}; a(0.5)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(true)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithBooleanParameterNull()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:Boolean):void {}; a(null)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(false)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithBooleanParameterUndefined()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:Boolean):void {}; a(undefined)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(false)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithStringParameterLiteral()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:String):void {}; a(\"hi\");", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(\"hi\")");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithStringParameterNull()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:String):void {}; a(null);", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(null)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithStringParameterUndefined()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:String):void {}; a(undefined);", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(null)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithStringParameterStringVar()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:String):void {}; var b:String; a(b);", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(b)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithStringParameterAnyTypeVar()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:String):void {}; var b:*; a(b);", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(org.apache.royale.utils.Language.string(b))");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithStringParameterToStringFunctionCall()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:String):void {}; var b:Object; a(b.toString());", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(b.toString())");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithStringParameterXMLVarChild()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:String):void {}; var b:XML; a(b.child);", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(org.apache.royale.utils.Language.string(b.child('child')))");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithNumberParameterDateProperty()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function a(foo:Number):void {}; var b:Date; a(b.month);", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(b.getMonth())");
+    }
+
     protected IBackend createBackend()
     {
         return new RoyaleBackend();
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleFieldMembers.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleFieldMembers.java
index ea844f8..5a8af9a 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleFieldMembers.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleFieldMembers.java
@@ -82,6 +82,30 @@
     }
 
     @Test
+    public void testField_withTypeValue_IntDecimal()
+    {
+        IVariableNode node = getField("var foo:int = -123.4;");
+        asBlockWalker.visitVariable(node);
+        assertOut("/**\n * @export\n * @type {number}\n */\nRoyaleTest_A.prototype.foo = -123");
+    }
+
+    @Test
+    public void testField_withTypeValue_UintDecimal()
+    {
+        IVariableNode node = getField("var foo:uint = 123.4;");
+        asBlockWalker.visitVariable(node);
+        assertOut("/**\n * @export\n * @type {number}\n */\nRoyaleTest_A.prototype.foo = 123");
+    }
+
+    @Test
+    public void testField_withTypeValue_UintNegative()
+    {
+        IVariableNode node = getField("var foo:uint = -123;");
+        asBlockWalker.visitVariable(node);
+        assertOut("/**\n * @export\n * @type {number}\n */\nRoyaleTest_A.prototype.foo = 4294967173");
+    }
+
+    @Test
     public void testVariable_withTypeValue_ArrayElementType()
     {
         IVariableNode node = (IVariableNode)getNode("public class A { function foobar():void {var foo:Number = bar[0];var bar:B;}}\n[ArrayElementType(\"Number\")]\nclass B {}",
@@ -115,7 +139,7 @@
     {
         IVariableNode node = getField("protected var foo:Vector.<Foo>;");
         asBlockWalker.visitVariable(node);
-        assertOut("/**\n * @protected\n * @type {Array}\n */\nRoyaleTest_A.prototype.foo");
+        assertOut("/**\n * @protected\n * @type {Array.<Foo>}\n */\nRoyaleTest_A.prototype.foo");
     }
 
     @Override
@@ -124,7 +148,7 @@
     {
         IVariableNode node = getField("protected var foo:Vector.<Vector.<Vector.<Foo>>>;");
         asBlockWalker.visitVariable(node);
-        assertOut("/**\n * @protected\n * @type {Array}\n */\nRoyaleTest_A.prototype.foo");
+        assertOut("/**\n * @protected\n * @type {Array.<Array.<Array.<Foo>>>}\n */\nRoyaleTest_A.prototype.foo");
     }
 
     @Override
@@ -185,7 +209,7 @@
     	IClassNode node = (IClassNode) getNode("import custom.custom_namespace;use namespace custom_namespace;public static var foo:Object = initFoo(); custom_namespace static function initFoo():Object { return null; }",
         		IClassNode.class, WRAP_LEVEL_CLASS);
         asBlockWalker.visitClass(node);
-        assertOut("/**\n * @constructor\n */\nRoyaleTest_A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('RoyaleTest_A', RoyaleTest_A);\n\n\n/**\n * @export\n * @type {Object}\n */\nRoyaleTest_A.foo;\n\n\n/**\n * @return {Object}\n */\nRoyaleTest_A[\"http://ns.apache.org/2017/custom/namespace::initFoo\"] = function() {\n  return null;\n};\n\nRoyaleTest_A.foo = RoyaleTest_A[\"http://ns.apache.org/2017/custom/namespace::initFoo\"]();\n\n");
+        assertOut("/**\n * @constructor\n */\nRoyaleTest_A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('RoyaleTest_A', RoyaleTest_A);\n\n\n/**\n * @export\n * @type {Object}\n */\nRoyaleTest_A.foo;\n\n\n/**\n * @export\n * @return {Object}\n */\nRoyaleTest_A.http_$$ns_apache_org$2017$custom$namespace__initFoo = function() {\n  return null;\n};\n\nRoyaleTest_A.foo = RoyaleTest_A.http_$$ns_apache_org$2017$custom$namespace__initFoo();\n\n");
     }
     
     @Test
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleGlobalClasses.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleGlobalClasses.java
index 4489082..23d50fa 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleGlobalClasses.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleGlobalClasses.java
@@ -19,6 +19,8 @@
 
 package org.apache.royale.compiler.internal.codegen.js.royale;
 
+import java.io.File;
+
 import org.apache.royale.compiler.driver.IBackend;
 import org.apache.royale.compiler.internal.codegen.js.goog.TestGoogGlobalClasses;
 import org.apache.royale.compiler.internal.driver.js.royale.RoyaleBackend;
@@ -122,27 +124,59 @@
         assertOut("var /** @type {number} */ a = 16");
     }
 
-    @Ignore
+    @Test
     public void testArrayRemoveAt()
     {
-    	// requires FP19 or newer
-        IBinaryOperatorNode node = getBinaryNode("var a:Array = new Array(); a.removeAt(2)");
-        IFunctionCallNode parentNode = (IFunctionCallNode)(node.getParent());
-        asBlockWalker.visitFunctionCall(parentNode);
-        assertOut("a.splice(2, 1)");
-    }
-
-    @Ignore
-    public void testArrayInsertAt()
-    {
-    	// requires FP19 or newer
-        IBinaryOperatorNode node = getBinaryNode("var a:Array = new Array(); a.insertAt(2, 'foo')");
-        IFunctionCallNode parentNode = (IFunctionCallNode)(node.getParent());
-        asBlockWalker.visitFunctionCall(parentNode);
-        assertOut("a.splice(2, 0, 'foo')");
+    	File pg = testAdapter.getPlayerglobal();
+    	if (arrayHasInsertAtRemoveAt(pg))
+    	{
+	    	// requires FP19 or newer
+	        IBinaryOperatorNode node = getBinaryNode("var a:Array = new Array(); a.removeAt(2)");
+	        IFunctionCallNode parentNode = (IFunctionCallNode)(node.getParent());
+	        asBlockWalker.visitFunctionCall(parentNode);
+	        assertOut("a.splice(2, 1)");
+    	}
     }
 
     @Test
+    public void testArrayInsertAt()
+    {
+    	File pg = testAdapter.getPlayerglobal();
+    	if (arrayHasInsertAtRemoveAt(pg))
+    	{
+	    	// requires FP19 or newer
+	        IBinaryOperatorNode node = getBinaryNode("var a:Array = new Array(); a.insertAt(2, 'foo')");
+	        IFunctionCallNode parentNode = (IFunctionCallNode)(node.getParent());
+	        asBlockWalker.visitFunctionCall(parentNode);
+	        assertOut("a.splice(2, 0, 'foo')");
+    	}
+    }
+
+    private boolean arrayHasInsertAtRemoveAt(File pg) {
+    	if (pg == null) return true;
+    	String path = pg.getAbsolutePath();
+    	String[] parts = path.split("/");
+    	if (path.contains("\\"))
+    		parts = path.split("\\\\");
+    	for (String part : parts)
+    	{
+    		if (part.contains("."))
+    		{
+    			// see if it is the playerglobal version string
+    			String[] versionParts = part.split("\\.");
+    			if (versionParts.length != 2) return false;
+    			try {
+	    			int major = Integer.parseInt(versionParts[0]);
+	    			if (major >= 19) return true;
+    			} catch (NumberFormatException e)
+    			{    				
+    			}
+    		}
+    	}
+		return false;
+	}
+
+	@Test
     public void testArraySortNoArgs()
     {
         IBinaryOperatorNode node = getBinaryNode("var a:Array = new Array();a.sort()");
@@ -253,6 +287,16 @@
         asBlockWalker.visitVariable(node);
         assertOut("var /** @type {number} */ a = Math[\"PI\"]");
     }
+    
+    @Override
+    @Test
+    public void testClass()
+    {
+        IVariableNode node = getVariable("var a:Class = String; var b:* = new a('test')");
+        node = (IVariableNode)(node.getParent().getChild(1));
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {*} */ b = org.apache.royale.utils.Language.resolveUncertain(new a('test'))");
+    }
 
     @Test
     public void testDateSetSeconds()
@@ -345,7 +389,7 @@
         IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>(['Hello', 'World']);");
         asBlockWalker.visitVariable(node);
         //MXMLC does not report an error.  Should we?
-        assertOut("var /** @type {Array} */ a = org.apache.royale.utils.Language.Vector(['Hello', 'World'], 'String')");
+        assertOut("var /** @type {Array.<string>} */ a = new (org.apache.royale.utils.Language.synthVector('String'))(['Hello', 'World'])");
     }
 
     @Test
@@ -353,7 +397,7 @@
     {
         IVariableNode node = getVariable("var a:Vector.<String> = new <String>[];");
         asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {Array} */ a = []");
+        assertOut("var /** @type {Array.<string>} */ a = org.apache.royale.utils.Language.synthVector('String')['coerce']([])");
     }
 
     @Test
@@ -361,7 +405,7 @@
     {
         IVariableNode node = getVariable("var a:Vector.<int> = new <int>[0, 1, 2, 3];");
         asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {Array} */ a = [0, 1, 2, 3]");
+        assertOut("var /** @type {Array.<number>} */ a = org.apache.royale.utils.Language.synthVector('int')['coerce']([0, 1, 2, 3])");
     }
 
     @Test
@@ -369,7 +413,7 @@
     {
         IVariableNode node = getVariable("var a:Vector.<String> = new <String>[\"one\", \"two\", \"three\";");
         asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {Array} */ a = [\"one\", \"two\", \"three\"]");
+        assertOut("var /** @type {Array.<string>} */ a = org.apache.royale.utils.Language.synthVector('String')['coerce']([\"one\", \"two\", \"three\"])");
     }
     
     @Test
@@ -377,7 +421,7 @@
     {
         IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>();");
         asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {Array} */ a = org.apache.royale.utils.Language.Vector()");
+        assertOut("var /** @type {Array.<string>} */ a = new (org.apache.royale.utils.Language.synthVector('String'))()");
     }
 
     @Test
@@ -386,7 +430,7 @@
         IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>('Hello', 'World');");
         asBlockWalker.visitVariable(node);
         //MXMLC does not report an error.  Should we?
-        assertOut("var /** @type {Array} */ a = org.apache.royale.utils.Language.Vector('Hello', 'String')");
+        assertOut("var /** @type {Array.<string>} */ a = new (org.apache.royale.utils.Language.synthVector('String'))('Hello', 'World')");
     }
 
     @Test
@@ -395,7 +439,7 @@
         IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>('Hello', 'World', 'Three');");
         asBlockWalker.visitVariable(node);
         //MXMLC does not report an error.  Should we?
-        assertOut("var /** @type {Array} */ a = org.apache.royale.utils.Language.Vector('Hello', 'String')");
+        assertOut("var /** @type {Array.<string>} */ a = new (org.apache.royale.utils.Language.synthVector('String'))('Hello', 'World', 'Three')");
     }
 
     @Test
@@ -403,7 +447,7 @@
     {
         IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>(30);");
         asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {Array} */ a = org.apache.royale.utils.Language.Vector(30, 'String')");
+        assertOut("var /** @type {Array.<string>} */ a = new (org.apache.royale.utils.Language.synthVector('String'))(30)");
     }
 
     @Test
@@ -412,7 +456,7 @@
         IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>(30, 40);");
         asBlockWalker.visitVariable(node);
         //MXMLC does not report an error.  Should we?
-        assertOut("var /** @type {Array} */ a = org.apache.royale.utils.Language.Vector(30, 'String')");
+        assertOut("var /** @type {Array.<string>} */ a = new (org.apache.royale.utils.Language.synthVector('String'))(30, 40)");
     }
 
     @Test
@@ -421,10 +465,357 @@
         IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>(['Hello', 'World']);");
         asBlockWalker.visitVariable(node);
         //MXMLC does not report an error.  Should we?
-        assertOut("var /** @type {Array} */ a = org.apache.royale.utils.Language.Vector(['Hello', 'World'], 'String')");
+        assertOut("var /** @type {Array.<string>} */ a = new (org.apache.royale.utils.Language.synthVector('String'))(['Hello', 'World'])");
+    }
+    
+    @Test
+    public void testVectorSetLength()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var a:Vector.<String> = new Vector.<String>(); a.length = 20)");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("a[org.apache.royale.utils.Language.SYNTH_TAG_FIELD].length = 20");
+    }
+    
+    @Test
+    public void testCustomVectorSetLength()
+    {
+        project.config.setJsVectorEmulationClass(null, "Anything");
+        IBinaryOperatorNode node = getBinaryNode("var a:Vector.<String> = new Vector.<String>(); a.length = 20)");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("a.length = 20");
+    }
+    
+    @Test
+    public void testVectorRemoveAt()
+    {
+    	File pg = testAdapter.getPlayerglobal();
+    	if (arrayHasInsertAtRemoveAt(pg))
+    	{
+	    	// requires FP19 or newer
+	        IBinaryOperatorNode node = getBinaryNode("var a:Vector.<String> = new Vector.<String>(); a.removeAt(2)");
+	        IFunctionCallNode parentNode = (IFunctionCallNode)(node.getParent());
+	        asBlockWalker.visitFunctionCall(parentNode);
+	        assertOut("a['removeAt'](2)");
+    	}
+    }
+    
+    @Test
+    public void testCustomVectorRemoveAt()
+    {
+        project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IBinaryOperatorNode node = getBinaryNode("var a:Vector.<String> = new Vector.<String>(); a.removeAt(2)");
+        IFunctionCallNode parentNode = (IFunctionCallNode)(node.getParent());
+        asBlockWalker.visitFunctionCall(parentNode);
+        assertOut("a.removeAt(2)");
+    }
+    
+    @Test
+    public void testCustomVectorAsArrayRemoveAt()
+    {
+        
+        project.config.setJsVectorEmulationClass(null, "Array");
+        IBinaryOperatorNode node = getBinaryNode("var a:Vector.<String> = new Vector.<String>(); a.removeAt(2)");
+        IFunctionCallNode parentNode = (IFunctionCallNode)(node.getParent());
+        asBlockWalker.visitFunctionCall(parentNode);
+        assertOut("a.splice(2, 1)[0]");
     }
 
     @Test
+    public void testVectorInsertAt()
+    {
+    	File pg = testAdapter.getPlayerglobal();
+    	if (arrayHasInsertAtRemoveAt(pg))
+    	{
+	    	// requires FP19 or newer
+	        IBinaryOperatorNode node = getBinaryNode("var a:Vector.<String> = new Vector.<String>(); a.insertAt(2, 'foo')");
+	        IFunctionCallNode parentNode = (IFunctionCallNode)(node.getParent());
+	        asBlockWalker.visitFunctionCall(parentNode);
+	        assertOut("a['insertAt'](2, 'foo')");
+    	}
+    }
+    
+    @Test
+    public void testCustomVectorInsertAt()
+    {
+        project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IBinaryOperatorNode node = getBinaryNode("var a:Vector.<String> = new Vector.<String>(); a.insertAt(2, 'foo')");
+        IFunctionCallNode parentNode = (IFunctionCallNode)(node.getParent());
+        asBlockWalker.visitFunctionCall(parentNode);
+        assertOut("a.insertAt(2, 'foo')");
+    }
+    
+    @Test
+    public void testCustomVectorAsArrayInsertAt()
+    {
+        project.config.setJsVectorEmulationClass(null, "Array");
+        IBinaryOperatorNode node = getBinaryNode("var a:Vector.<String> = new Vector.<String>(); a.insertAt(2, 'foo')");
+        IFunctionCallNode parentNode = (IFunctionCallNode)(node.getParent());
+        asBlockWalker.visitFunctionCall(parentNode);
+        assertOut("a.splice(2, 0, 'foo')");
+    }
+
+    @Test
+    public void testCustomVector()
+    {
+    	project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>(['Hello', 'World']);");
+        asBlockWalker.visitVariable(node);
+        //MXMLC does not report an error.  Should we?
+        assertOut("var /** @type {CustomVector} */ a = new CustomVector(['Hello', 'World'], 'String')");
+    }
+
+    @Test
+    public void testCustomVectorLiteral_1()
+    {
+    	project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IVariableNode node = getVariable("var a:Vector.<String> = new <String>[];");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {CustomVector} */ a = new CustomVector([], 'String')");
+    }
+    
+    @Test
+    public void testCustomVectorLiteral_1a()
+    {
+        project.config.setJsVectorEmulationClass(null, "Array");
+        IVariableNode node = getVariable("var a:Vector.<String> = new <String>[];");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {Array} */ a = []");
+    }
+
+    @Test
+    public void testCustomVectorLiteral_2()
+    {
+    	project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IVariableNode node = getVariable("var a:Vector.<int> = new <int>[0, 1, 2, 3];");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {CustomVector} */ a = new CustomVector([0, 1, 2, 3], 'int')");
+    }
+    
+    @Test
+    public void testCustomVectorLiteral_2a()
+    {
+        project.config.setJsVectorEmulationClass(null, "Array");
+        IVariableNode node = getVariable("var a:Vector.<int> = new <int>[0, 1, 2, 3];");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {Array} */ a = [0, 1, 2, 3]");
+    }
+
+    @Test
+    public void testCustomVectorLiteral_3()
+    {
+    	project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IVariableNode node = getVariable("var a:Vector.<String> = new <String>[\"one\", \"two\", \"three\"];");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {CustomVector} */ a = new CustomVector([\"one\", \"two\", \"three\"], 'String')");
+    }
+    
+    @Test
+    public void testCustomVectorLiteral_3a()
+    {
+        project.config.setJsVectorEmulationClass(null, "Array");
+        IVariableNode node = getVariable("var a:Vector.<String> = new <String>[\"one\", \"two\", \"three\"];");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {Array} */ a = [\"one\", \"two\", \"three\"]");
+    }
+    
+    @Test
+    public void testCustomVectorNoArgs()
+    {
+    	project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>();");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {CustomVector} */ a = new CustomVector([], 'String')");
+    }
+    
+    @Test
+    public void testCustomVectorNoArgs2()
+    {
+        project.config.setJsVectorEmulationClass(null, "Array");
+        IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>();");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {Array} */ a = []");
+    }
+
+    @Test
+    public void testCustomVectorStringArgs()
+    {
+    	project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>('Hello', 'World');");
+        asBlockWalker.visitVariable(node);
+        //MXMLC does not report an error.  Should we?
+        assertOut("var /** @type {CustomVector} */ a = new CustomVector('Hello', 'String')");
+    }
+
+    @Test
+    public void testCustomVectorStringArgs3()
+    {
+    	project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>('Hello', 'World', 'Three');");
+        asBlockWalker.visitVariable(node);
+        //MXMLC does not report an error.  Should we?
+        assertOut("var /** @type {CustomVector} */ a = new CustomVector('Hello', 'String')");
+    }
+
+    @Test
+    public void testCustomVectorSizeArg()
+    {
+    	project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>(30);");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {CustomVector} */ a = new CustomVector(30, 'String')");
+    }
+    
+    @Test
+    public void testCustomVectorSizeArg2()
+    {
+        project.config.setJsVectorEmulationClass(null, "Array");
+        IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>(30);");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {Array} */ a = org.apache.royale.utils.Language.arrayAsVector(30, 'String')");
+    }
+    
+    @Test
+    public void testCustomVectorSizeAndFixedArgs()
+    {
+    	project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>(30, true);");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {CustomVector} */ a = new CustomVector(30, 'String', true)");
+    }
+    
+    @Test
+    public void testCustomVectorSizeAndFixedArgs2()
+    {
+        project.config.setJsVectorEmulationClass(null, "Array");
+        IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>(30, true);");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {Array} */ a = org.apache.royale.utils.Language.arrayAsVector(30, 'String')");
+    }
+
+    @Test
+    public void testCustomVectorNumberArgs()
+    {
+    	project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>(30, 40);");
+        asBlockWalker.visitVariable(node);
+        //MXMLC does not report an error.  Should we?
+        assertOut("var /** @type {CustomVector} */ a = new CustomVector(30, 'String')");
+    }
+    
+    @Test
+    public void testCustomVectorNumberArgs2()
+    {
+        project.config.setJsVectorEmulationClass(null, "Array");
+        IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>(30, 40);");
+        asBlockWalker.visitVariable(node);
+        //MXMLC does not report an error.  Should we?
+        assertOut("var /** @type {Array} */ a = org.apache.royale.utils.Language.arrayAsVector(30, 'String')");
+    }
+
+    @Test
+    public void testCustomVectorArrayArg()
+    {
+    	project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>(['Hello', 'World']);");
+        asBlockWalker.visitVariable(node);
+        //MXMLC does not report an error.  Should we?
+        assertOut("var /** @type {CustomVector} */ a = new CustomVector(['Hello', 'World'], 'String')");
+    }
+    
+    @Test
+    public void testCustomVectorArrayArg2()
+    {
+        project.config.setJsVectorEmulationClass(null, "Array");
+        IVariableNode node = getVariable("var a:Vector.<String> = new Vector.<String>(['Hello', 'World']);");
+        asBlockWalker.visitVariable(node);
+        //MXMLC does not report an error.  Should we?
+        assertOut("var /** @type {Array} */ a = org.apache.royale.utils.Language.arrayAsVector(['Hello', 'World'], 'String')");
+    }
+    
+    @Test
+    public void testDefaultVectorClassRepresentation()
+    {
+        IVariableNode node = getVariable("var a:Class = Vector.<String>;");
+        asBlockWalker.visitVariable(node);
+        //MXMLC does not report an error.  Should we?
+        assertOut("var /** @type {Object} */ a = org.apache.royale.utils.Language.synthVector('String')");
+    }
+    
+    @Test
+    public void testCustomVectorClassRepresentation()
+    {
+        project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IVariableNode node = getVariable("var a:Class = Vector.<String>;");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {Object} */ a = CustomVector");
+    }
+    
+    @Test
+    public void testCustomVectorClassRepresentation2()
+    {
+        project.config.setJsVectorEmulationClass(null, "Array");
+        IVariableNode node = getVariable("var a:Class = Vector.<String>;");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {Object} */ a = Array");
+    }
+    
+    @Test
+    public void testDefaultVectorSortNumericArg()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var a:Vector.<Number> = new Vector.<Number>();a.sort(Array.NUMERIC)");
+        IFunctionCallNode parentNode = (IFunctionCallNode)(node.getParent());
+        asBlockWalker.visitFunctionCall(parentNode);
+        assertOut("org.apache.royale.utils.Language.sort(a, 16)");
+    }
+    
+    @Test
+    public void testCustomVectorRepresentationSortNumericArg()
+    {
+        project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IBinaryOperatorNode node = getBinaryNode("var a:Vector.<Number> = new Vector.<Number>();a.sort(Array.NUMERIC)");
+        IFunctionCallNode parentNode = (IFunctionCallNode)(node.getParent());
+        asBlockWalker.visitFunctionCall(parentNode);
+        assertOut("a.sort(16)");
+    }
+    
+    @Test
+    public void testCustomVectorAsArrayRepresentationSortNumericArg()
+    {
+        project.config.setJsVectorEmulationClass(null, "Array");
+        IBinaryOperatorNode node = getBinaryNode("var a:Vector.<Number> = new Vector.<Number>();a.sort(Array.NUMERIC)");
+        IFunctionCallNode parentNode = (IFunctionCallNode)(node.getParent());
+        asBlockWalker.visitFunctionCall(parentNode);
+        assertOut("org.apache.royale.utils.Language.sort(a, 16)");
+    }
+    
+    @Override
+    @Test
+    public void testBoolean()
+    {
+        IVariableNode node = getVariable("var a:Boolean = new Boolean(1);");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {boolean} */ a = Boolean(1)");
+    }
+    
+    @Override
+    @Test
+    public void testNumber()
+    {
+        IVariableNode node = getVariable("var a:Number = new Number(\"1\");");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {number} */ a = Number(\"1\")");
+    }
+    
+    @Override
+    @Test
+    public void testString()
+    {
+        IVariableNode node = getVariable("var a:String = new String(\"100\");");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {string} */ a = String(\"100\")");
+    }
+    
+    @Test
     public void testXML()
     {
         IVariableNode node = getVariable("var a:XML = new XML(\"<top attr1='cat'><child attr2='dog'><grandchild attr3='fish'>text</grandchild></child></top>\");");
@@ -675,7 +1066,7 @@
         IASNode parentNode = node.getParent();
         node = (IVariableNode) parentNode.getChild(1);
         asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {number} */ b = a.child('child').length()");
+        assertOut("var /** @type {number} */ b = (a.child('child').length()) >> 0");
     }
     
     @Test
@@ -688,6 +1079,16 @@
         assertOut("var /** @type {XMLList} */ b = a.descendants('child')");
     }
     
+    @Test
+    public void testXMLDoubleDotTwice()
+    {
+        IVariableNode node = getVariable("var a:XML = new XML(\"<top attr1='cat'><child attr2='dog'><grandchild attr3='fish'>text</grandchild></child></top>\");var b:XMLList = a..child..grandchild;");
+        IASNode parentNode = node.getParent();
+        node = (IVariableNode) parentNode.getChild(1);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {XMLList} */ b = a.descendants('child').descendants('grandchild')");
+    }
+    
     @Ignore
     public void testXMLDoubleDotLiteral()
     {
@@ -835,6 +1236,14 @@
     }
     
     @Test
+    public void testXMLSetChildAttributeBracketProp()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var z:String = 'prop';var a:XML = new XML(\"<top attr1='cat'><child attr2='dog'><grandchild attr3='fish'>text</grandchild></child></top>\");a.child.@['attr3'] = 'foo'");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("a.child('child').setAttribute('attr3', 'foo')");
+    }
+    
+    @Test
     public void testXMLListSetAttribute()
     {
         IBinaryOperatorNode node = getBinaryNode("var a:XMLList;a[1].@bar = 'foo'");
@@ -921,7 +1330,7 @@
     {
     	IForLoopNode node = getForLoopNode("var a:XML = new XML(\"<top attr1='cat'><child attr2='dog'><grandchild attr3='fish'>text</grandchild></child></top>\");for each (var p:XMLList in a) var i:int = p.length();");
         asBlockWalker.visitForLoop(node);
-        assertOut("var foreachiter0_target = a;\nfor (var foreachiter0 in foreachiter0_target.elementNames()) \n{\nvar p = foreachiter0_target[foreachiter0];\n\n  var /** @type {number} */ i = p.length();}\n");
+        assertOut("var foreachiter0_target = a;\nfor (var foreachiter0 in foreachiter0_target.elementNames()) \n{\nvar p = foreachiter0_target[foreachiter0];\n\n  var /** @type {number} */ i = (p.length()) >> 0;}\n");
     }
     
     @Test
@@ -929,7 +1338,7 @@
     {
     	IForLoopNode node = getForLoopNode("var a:*;for each (var p:XML in (a as XMLList)) var i:int = p.length();");
         asBlockWalker.visitForLoop(node);
-        assertOut("var foreachiter0_target = org.apache.royale.utils.Language.as(a, XMLList);\nfor (var foreachiter0 in foreachiter0_target.elementNames()) \n{\nvar p = foreachiter0_target[foreachiter0];\n\n  var /** @type {number} */ i = p.length();}\n");
+        assertOut("var foreachiter0_target = org.apache.royale.utils.Language.as(a, XMLList);\nfor (var foreachiter0 in foreachiter0_target.elementNames()) \n{\nvar p = foreachiter0_target[foreachiter0];\n\n  var /** @type {number} */ i = (p.length()) >> 0;}\n");
     }
     
     @Test
@@ -937,7 +1346,7 @@
     {
     	IForLoopNode node = getForLoopNode("var a:*;for each (var p:XML in XMLList(a)) var i:int = p.length();");
         asBlockWalker.visitForLoop(node);
-        assertOut("var foreachiter0_target = XMLList(a);\nfor (var foreachiter0 in foreachiter0_target.elementNames()) \n{\nvar p = foreachiter0_target[foreachiter0];\n\n  var /** @type {number} */ i = p.length();}\n");
+        assertOut("var foreachiter0_target = XMLList.conversion(a);\nfor (var foreachiter0 in foreachiter0_target.elementNames()) \n{\nvar p = foreachiter0_target[foreachiter0];\n\n  var /** @type {number} */ i = (p.length()) >> 0;}\n");
     }
     
     @Test
@@ -1056,7 +1465,7 @@
                 "import custom.TestProxy; public class B {public function b() { var a:TestProxy = new TestProxy();for each (var p:String in a) var i:int = p.length; }}",
                 IForLoopNode.class, WRAP_LEVEL_PACKAGE, true);
         asBlockWalker.visitForLoop(node);
-        assertOut("var foreachiter0_target = a;\nfor (var foreachiter0 in foreachiter0_target.propertyNames()) \n{\nvar p = foreachiter0_target.getProperty(foreachiter0);\n\n  var /** @type {number} */ i = p.length;}\n");
+        assertOut("var foreachiter0_target = a;\nfor (var foreachiter0 in foreachiter0_target.propertyNames()) \n{\nvar p = foreachiter0_target.getProperty(foreachiter0);\n\n  var /** @type {number} */ i = (p.length) >> 0;}\n");
     }
     
     @Test
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleGlobalFunctions.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleGlobalFunctions.java
index 2c6eaf7..a06bfa0 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleGlobalFunctions.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleGlobalFunctions.java
@@ -100,11 +100,20 @@
         asBlockWalker.visitVariable(node);
         assertOut("var /** @type {Array} */ a = Array(['Hello', 'World'])");
     }
+    
+    @Override
+    @Test
+    public void testObject()
+    {
+        IVariableNode node = getVariable("var a:Object = Object(\"1\");");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {Object} */ a = org.apache.royale.utils.Language.resolveUncertain(Object(\"1\"))");
+    }
 
     @Test
     public void testParseInt()
     {
-        IVariableNode node = getVariable("var a:int = parseInt('1.8');");
+        IVariableNode node = getVariable("var a:Number = parseInt('1.8');");
         asBlockWalker.visitVariable(node);
         assertOut("var /** @type {number} */ a = parseInt('1.8', undefined)");
     }
@@ -112,7 +121,7 @@
     @Test
     public void testParseIntTwoArgs()
     {
-        IVariableNode node = getVariable("var a:int = parseInt('1.8', 16);");
+        IVariableNode node = getVariable("var a:Number = parseInt('1.8', 16);");
         asBlockWalker.visitVariable(node);
         assertOut("var /** @type {number} */ a = parseInt('1.8', 16)");
     }
@@ -159,6 +168,24 @@
     {
         IVariableNode node = getVariable("var a:Vector.<String> = Vector.<String>(['Hello', 'World']);");
         asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {Array.<string>} */ a = org.apache.royale.utils.Language.synthVector('String')['coerce'](['Hello', 'World'])");
+    }
+    
+    @Test
+    public void testCustomVector()
+    {
+        project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IVariableNode node = getVariable("var a:Vector.<String> = Vector.<String>(['Hello', 'World']);");
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {CustomVector} */ a = new CustomVector(['Hello', 'World'], 'String')");
+    }
+    
+    @Test
+    public void testCustomVectorAsArray()
+    {
+        project.config.setJsVectorEmulationClass(null, "Array");
+        IVariableNode node = getVariable("var a:Vector.<String> = Vector.<String>(['Hello', 'World']);");
+        asBlockWalker.visitVariable(node);
         assertOut("var /** @type {Array} */ a = ['Hello', 'World'].slice()");
     }
 
@@ -184,8 +211,29 @@
         IVariableNode node = getVariable("var a:Vector.<String> = Vector.<String>(30);");
         asBlockWalker.visitVariable(node);
         // MXMLC doesn't report an error either.  Maybe we should. 
+        assertOut("var /** @type {Array.<string>} */ a = org.apache.royale.utils.Language.synthVector('String')['coerce'](30)");
+    }
+    
+    @Test
+    public void testCustomVectorSizeArg()
+    {
+        project.config.setJsVectorEmulationClass(null, "CustomVector");
+        IVariableNode node = getVariable("var a:Vector.<String> = Vector.<String>(30);");
+        asBlockWalker.visitVariable(node);
+        // MXMLC doesn't report an error either.  Maybe we should.
+        assertOut("var /** @type {CustomVector} */ a = new CustomVector(30, 'String')");
+    }
+    
+    @Test
+    public void testCustomVectorAsArraySizeArg()
+    {
+        project.config.setJsVectorEmulationClass(null, "Array");
+        IVariableNode node = getVariable("var a:Vector.<String> = Vector.<String>(30);");
+        asBlockWalker.visitVariable(node);
+        // MXMLC doesn't report an error either.  Maybe we should.
         assertOut("var /** @type {Array} */ a = 30.slice()");
     }
+    
 
     @Test
     public void testVectorNumberArgs()
@@ -200,7 +248,7 @@
     {
         IVariableNode node = getVariable("var a:Vector.<String> = Vector.<String>(['Hello', 'World']);");
         asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {Array} */ a = ['Hello', 'World'].slice()");
+        assertOut("var /** @type {Array.<string>} */ a = org.apache.royale.utils.Language.synthVector('String')['coerce'](['Hello', 'World'])");
     }
 
     @Override
@@ -234,7 +282,7 @@
         // (erikdebruin) E4X in Javascript is obsolete.
         //               Ref.: https://developer.mozilla.org/en-US/docs/E4X
         
-        assertOut("var /** @type {XMLList} */ a = XMLList('<!-- comment -->')");
+        assertOut("var /** @type {XMLList} */ a = XMLList.conversion('<!-- comment -->')");
     }
 
     @Test
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleInterface.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleInterface.java
index 2ee8941..6dc1bca 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleInterface.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleInterface.java
@@ -90,7 +90,7 @@
                 + "function baz1():Object;"
                 + "function baz2(value:Object):void;}");
         asBlockWalker.visitInterface(node);
-        assertOut("/**\n * @interface\n */\nIA = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('IA', IA);\n/**\n * @return {Object}\n */\nIA.prototype.baz1 = function() {\n};\n/**\n * @param {Object} value\n */\nIA.prototype.baz2 = function(value) {\n};");
+        assertOut("/**\n * @interface\n */\nIA = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('IA', IA);\n/**\n * @export\n * @return {Object}\n */\nIA.prototype.baz1 = function() {\n};\n/**\n * @export\n * @param {Object} value\n */\nIA.prototype.baz2 = function(value) {\n};");
     }
 
     @Override
@@ -103,7 +103,7 @@
                 + "function baz1():Object;"
                 + "function baz2(value:Object):void;}");
         asBlockWalker.visitInterface(node);
-        assertOut("/**\n * @interface\n */\nIA = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('IA', IA);\n/**  * @type {Object}\n */IA.prototype.foo1;\n/**\n * @return {Object}\n */\nIA.prototype.baz1 = function() {\n};\n/**\n * @param {Object} value\n */\nIA.prototype.baz2 = function(value) {\n};");
+        assertOut("/**\n * @interface\n */\nIA = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('IA', IA);\n/**  * @type {Object}\n */IA.prototype.foo1;\n/**\n * @export\n * @return {Object}\n */\nIA.prototype.baz1 = function() {\n};\n/**\n * @export\n * @param {Object} value\n */\nIA.prototype.baz2 = function(value) {\n};");
     }
 
     protected IBackend createBackend()
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleMethodMembers.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleMethodMembers.java
index f05f4bc..b7664c2 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleMethodMembers.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleMethodMembers.java
@@ -38,7 +38,7 @@
     {
         IFunctionNode node = getMethod("function foo():int{  return -1;}");
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @return {number}\n */\nRoyaleTest_A.prototype.foo = function() {\n  return -1;\n}");
+        assertOut("/**\n * @export\n * @return {number}\n */\nRoyaleTest_A.prototype.foo = function() {\n  return -1;\n}");
     }
 
     @Override
@@ -47,7 +47,7 @@
     {
         IFunctionNode node = getMethod("function foo(bar):int{  return -1;}");
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @param {*} bar\n * @return {number}\n */\nRoyaleTest_A.prototype.foo = function(bar) {\n  return -1;\n}");
+        assertOut("/**\n * @export\n * @param {*} bar\n * @return {number}\n */\nRoyaleTest_A.prototype.foo = function(bar) {\n  return -1;\n}");
     }
 
     @Override
@@ -56,7 +56,7 @@
     {
         IFunctionNode node = getMethod("function foo(bar:String):int{  return -1;}");
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @param {string} bar\n * @return {number}\n */\nRoyaleTest_A.prototype.foo = function(bar) {\n  return -1;\n}");
+        assertOut("/**\n * @export\n * @param {string} bar\n * @return {number}\n */\nRoyaleTest_A.prototype.foo = function(bar) {\n  return -1;\n}");
     }
 
     @Override
@@ -65,7 +65,7 @@
     {
         IFunctionNode node = getMethod("function foo(bar:String = \"baz\"):int{  return -1;}");
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @param {string=} bar\n * @return {number}\n */\nRoyaleTest_A.prototype.foo = function(bar) {\n  bar = typeof bar !== 'undefined' ? bar : \"baz\";\n  return -1;\n}");
+        assertOut("/**\n * @export\n * @param {string=} bar\n * @return {number}\n */\nRoyaleTest_A.prototype.foo = function(bar) {\n  bar = typeof bar !== 'undefined' ? bar : \"baz\";\n  return -1;\n}");
     }
 
     @Override
@@ -74,7 +74,7 @@
     {
         IFunctionNode node = getMethod("function foo(bar:String, baz:int = null):int{  return -1;}");
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @param {string} bar\n * @param {number=} baz\n * @return {number}\n */\nRoyaleTest_A.prototype.foo = function(bar, baz) {\n  baz = typeof baz !== 'undefined' ? baz : null;\n  return -1;\n}");
+        assertOut("/**\n * @export\n * @param {string} bar\n * @param {number=} baz\n * @return {number}\n */\nRoyaleTest_A.prototype.foo = function(bar, baz) {\n  baz = typeof baz !== 'undefined' ? baz : null;\n  return -1;\n}");
     }
 
     @Test
@@ -82,7 +82,7 @@
     {
         IFunctionNode node = getMethodWithPackage("static const BAR:String = 'bar'; function foo(bar:String = RoyaleTest_A.BAR):int{  return -1;}");
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @param {string=} bar\n * @return {number}\n */\nfoo.bar.RoyaleTest_A.prototype.foo = function(bar) {\n  bar = typeof bar !== 'undefined' ? bar : foo.bar.RoyaleTest_A.BAR;\n  return -1;\n}");
+        assertOut("/**\n * @export\n * @param {string=} bar\n * @return {number}\n */\nfoo.bar.RoyaleTest_A.prototype.foo = function(bar) {\n  bar = typeof bar !== 'undefined' ? bar : foo.bar.RoyaleTest_A.BAR;\n  return -1;\n}");
     }
 
     @Override
@@ -91,7 +91,7 @@
     {
         IFunctionNode node = getMethod("function foo(bar:String, ...rest):int{  return -1;}");
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @param {string} bar\n * @param {...} rest\n * @return {number}\n */\nRoyaleTest_A.prototype.foo = function(bar, rest) {\n  rest = Array.prototype.slice.call(arguments, 1);\n  return -1;\n}");
+        assertOut("/**\n * @export\n * @param {string} bar\n * @param {...} rest\n * @return {number}\n */\nRoyaleTest_A.prototype.foo = function(bar, rest) {\n  rest = Array.prototype.slice.call(arguments, 1);\n  return -1;\n}");
     }
 
     @Override
@@ -100,7 +100,7 @@
     {
         IFunctionNode node = getMethod("import custom.custom_namespace;custom_namespace function foo(bar:String, baz:int = null):int{  return -1;}");
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @param {string} bar\n * @param {number=} baz\n * @return {number}\n */\nRoyaleTest_A.prototype[\"http://ns.apache.org/2017/custom/namespace::foo\"] = function(bar, baz) {\n  baz = typeof baz !== 'undefined' ? baz : null;\n  return -1;\n}");
+        assertOut("/**\n * @export\n * @param {string} bar\n * @param {number=} baz\n * @return {number}\n */\nRoyaleTest_A.prototype.http_$$ns_apache_org$2017$custom$namespace__foo = function(bar, baz) {\n  baz = typeof baz !== 'undefined' ? baz : null;\n  return -1;\n}");
     }
 
     //--------------------------------------------------------------------------
@@ -147,7 +147,7 @@
     {
         IClassNode node = (IClassNode) getNode("public function RoyaleTest_A(){}; private function foo(value:int):String{return value;}; private function bar():String{if(true){while(i){return this.foo(42);}}};", IClassNode.class, WRAP_LEVEL_CLASS);
         asBlockWalker.visitClass(node);
-        assertOut("/**\n * @constructor\n */\nRoyaleTest_A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('RoyaleTest_A', RoyaleTest_A);\n\n\n/**\n * @private\n * @param {number} value\n * @return {string}\n */\nRoyaleTest_A.prototype.foo = function(value) {\n  return value;\n};\n\n\n/**\n * @private\n * @return {string}\n */\nRoyaleTest_A.prototype.bar = function() {\n  if (true) {\n    while (i) {\n      return this.foo(42);\n    }\n  }\n};");
+        assertOut("/**\n * @constructor\n */\nRoyaleTest_A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('RoyaleTest_A', RoyaleTest_A);\n\n\n/**\n * @private\n * @param {number} value\n * @return {string}\n */\nRoyaleTest_A.prototype.foo = function(value) {\n  return org.apache.royale.utils.Language.string(value);\n};\n\n\n/**\n * @private\n * @return {string}\n */\nRoyaleTest_A.prototype.bar = function() {\n  if (true) {\n    while (i) {\n      return this.foo(42);\n    }\n  }\n};");
     }
 
     @Test
@@ -155,7 +155,7 @@
     {
         IClassNode node = (IClassNode) getNode("public function RoyaleTest_A(){}; private function foo(value:int):String{return value;}; private function bar():void{if(true){while(i){foo(42);}}};", IClassNode.class, WRAP_LEVEL_CLASS);
         asBlockWalker.visitClass(node);
-        assertOut("/**\n * @constructor\n */\nRoyaleTest_A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('RoyaleTest_A', RoyaleTest_A);\n\n\n/**\n * @private\n * @param {number} value\n * @return {string}\n */\nRoyaleTest_A.prototype.foo = function(value) {\n  return value;\n};\n\n\n/**\n * @private\n */\nRoyaleTest_A.prototype.bar = function() {\n  if (true) {\n    while (i) {\n      this.foo(42);\n    }\n  }\n};");
+        assertOut("/**\n * @constructor\n */\nRoyaleTest_A = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('RoyaleTest_A', RoyaleTest_A);\n\n\n/**\n * @private\n * @param {number} value\n * @return {string}\n */\nRoyaleTest_A.prototype.foo = function(value) {\n  return org.apache.royale.utils.Language.string(value);\n};\n\n\n/**\n * @private\n */\nRoyaleTest_A.prototype.bar = function() {\n  if (true) {\n    while (i) {\n      this.foo(42);\n    }\n  }\n};");
     }
 
     @Override
@@ -206,6 +206,14 @@
         assertOut("/**\n * @export\n * @return {string}\n */\nRoyaleTest_A.prototype.foo = function() {\n  \n/**\n * @const\n * @type {string}\n */\nvar A = 'Hello World';\n  return A;\n}");
     }
 
+    @Test
+    public void testAbstractMethod()
+    {
+        IClassNode node = (IClassNode) getNode("public abstract class A { public abstract function a(arg1:String):Object; }", IClassNode.class, WRAP_LEVEL_PACKAGE);
+        asBlockWalker.visitClass(node);
+        assertOut("/**\n * @constructor\n */\nA = function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('A', A);\n\n\n/**\n * @export\n * @param {string} arg1\n * @return {Object}\n */\nA.prototype.a = function(arg1) {\n};");
+    }
+
     @Override
     protected IBackend createBackend()
     {
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyalePackage.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyalePackage.java
index 15a4d07..53756f1 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyalePackage.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyalePackage.java
@@ -61,7 +61,7 @@
         // with block disallows implicit blocks from getting { }
 
         // (erikdebruin) the constuctor IS the class definition, in 'goog' JS,
-        //               therefor we need to write out implicit constructors 
+        //               therefor we need to write out implicit constructors
         //               (if I understand the term correctly)
 
         IFileNode node = compileAS("package {public class A{}}");
@@ -105,7 +105,13 @@
         		"    accessors: function () {return {};},\n" +
         		"    methods: function () {return {};}\n" +
         		"  };\n" +
-        		"};\n");
+        		"};\n"+
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n");
     }
 
     @Override
@@ -153,7 +159,13 @@
 				"    accessors: function () {return {};},\n" +
 				"    methods: function () {return {};}\n" +
         		"  };\n" +
-        		"};\n");
+        		"};\n"+
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n");
     }
 
     @Override
@@ -163,49 +175,63 @@
         IFileNode node = compileAS("package foo.bar.baz {public class A{public function A(){}}}");
         asBlockWalker.visitFile(node);
         assertOutWithMetadata("/**\n" +
-        		" * foo.bar.baz.A\n" +
-        		" *\n" +
-        		" * @fileoverview\n" +
-        		" *\n" +
-        		" * @suppress {checkTypes|accessControls}\n" +
-        		" */\n" +
-        		"\n" +
-        		"goog.provide('foo.bar.baz.A');\n" +
-        		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * @constructor\n" +
-        		" */\n" +
-        		"foo.bar.baz.A = function() {\n" +
-        		"};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Metadata\n" +
-        		" *\n" +
-        		" * @type {Object.<string, Array.<Object>>}\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
-        		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Reflection\n" +
-        		" *\n" +
-        		" * @return {Object.<string, Function>}\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-        		"  return {\n" +
+				" * foo.bar.baz.A\n" +
+				" *\n" +
+				" * @fileoverview\n" +
+				" *\n" +
+				" * @suppress {checkTypes|accessControls}\n" +
+				" */\n" +
+				"\n" +
+				"goog.provide('foo.bar.baz.A');\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @constructor\n" +
+				" */\n" +
+				"foo.bar.baz.A = function() {\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Metadata\n" +
+				" *\n" +
+				" * @type {Object.<string, Array.<Object>>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
 				"    variables: function () {return {};},\n" +
 				"    accessors: function () {return {};},\n" +
-        		"    methods: function () {\n" +
-        		"      return {\n" +
-        		"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
-        		"      };\n" +
-        		"    }\n" + 
-        		"  };\n" +
-        		"};\n");
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
+				"      };\n" +
+				"    }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n"
+		
+		);
     }
 
     @Override
@@ -215,54 +241,66 @@
         IFileNode node = compileAS("package foo.bar.baz {public class A{public function A(){if (a){for (var i:Object in obj){doit();}}}}}");
         asBlockWalker.visitFile(node);
         assertOutWithMetadata("/**\n" +
-        		" * foo.bar.baz.A\n" +
-        		" *\n" +
-        		" * @fileoverview\n" +
-        		" *\n" +
-        		" * @suppress {checkTypes|accessControls}\n" +
-        		" */\n" +
-        		"\n" +
-        		"goog.provide('foo.bar.baz.A');\n" +
-        		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * @constructor\n" +
-        		" */\n" +
-        		"foo.bar.baz.A = function() {\n" +
-        		"  if (a) {\n" +
-        		"    for (var /** @type {Object} */ i in obj) {\n" +
-        		"      doit();\n" +
-        		"    }\n" +
-        		"  }\n" +
-        		"};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Metadata\n" +
-        		" *\n" +
-        		" * @type {Object.<string, Array.<Object>>}\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
-        		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Reflection\n" +
-        		" *\n" +
-        		" * @return {Object.<string, Function>}\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-        		"  return {\n" +
+				" * foo.bar.baz.A\n" +
+				" *\n" +
+				" * @fileoverview\n" +
+				" *\n" +
+				" * @suppress {checkTypes|accessControls}\n" +
+				" */\n" +
+				"\n" +
+				"goog.provide('foo.bar.baz.A');\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @constructor\n" +
+				" */\n" +
+				"foo.bar.baz.A = function() {\n" +
+				"  if (a) {\n" +
+				"    for (var /** @type {Object} */ i in obj) {\n" +
+				"      doit();\n" +
+				"    }\n" +
+				"  }\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Metadata\n" +
+				" *\n" +
+				" * @type {Object.<string, Array.<Object>>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
 				"    variables: function () {return {};},\n" +
 				"    accessors: function () {return {};},\n" +
-        		"    methods: function () {\n" +
-        		"      return {\n" +
-        		"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
-        		"      };\n" +
-        		"    }\n" + 
-        		"  };\n" +
-        		"};\n");
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
+				"      };\n" +
+				"    }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n");
     }
 
     @Test
@@ -271,50 +309,62 @@
         IFileNode node = compileAS("package foo.bar.baz {[Event(name='add', type='mx.events.FlexEvent')]\npublic class A{public function A(){}}}");
         asBlockWalker.visitFile(node);
         assertOutWithMetadata("/**\n" +
-        		" * foo.bar.baz.A\n" +
-        		" *\n" +
-        		" * @fileoverview\n" +
-        		" *\n" +
-        		" * @suppress {checkTypes|accessControls}\n" +
-        		" */\n" +
-        		"\n" +
-        		"goog.provide('foo.bar.baz.A');\n" +
-        		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * @constructor\n" +
-        		" */\n" +
-        		"foo.bar.baz.A = function() {\n" +
-        		"};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Metadata\n" +
-        		" *\n" +
-        		" * @type {Object.<string, Array.<Object>>}\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
-        		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Reflection\n" +
-        		" *\n" +
-        		" * @return {Object.<string, Function>}\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-        		"  return {\n" +
+				" * foo.bar.baz.A\n" +
+				" *\n" +
+				" * @fileoverview\n" +
+				" *\n" +
+				" * @suppress {checkTypes|accessControls}\n" +
+				" */\n" +
+				"\n" +
+				"goog.provide('foo.bar.baz.A');\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @constructor\n" +
+				" */\n" +
+				"foo.bar.baz.A = function() {\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Metadata\n" +
+				" *\n" +
+				" * @type {Object.<string, Array.<Object>>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
 				"    variables: function () {return {};},\n" +
 				"    accessors: function () {return {};},\n" +
-        		"    methods: function () {\n" +
-        		"      return {\n" +
-        		"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
-        		"      };\n" +
-        		"    },\n" +
-        		"    metadata: function () { return [ { name: 'Event', args: [ { key: 'name', value: 'add' }, { key: 'type', value: 'mx.events.FlexEvent' } ] } ]; }\n" +
-        		"  };\n" +
-        		"};\n");
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
+				"      };\n" +
+				"    },\n" +
+				"    metadata: function () { return [ { name: 'Event', args: [ { key: 'name', value: 'add' }, { key: 'type', value: 'mx.events.FlexEvent' } ] } ]; }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n");
     }
 
     @Test
@@ -323,58 +373,71 @@
         IFileNode node = compileAS("package foo.bar.baz {[Event(name='add', type='mx.events.FlexEvent')]\npublic class A{public function A(){}\n[Before]\npublic function foo() {}}}");
         asBlockWalker.visitFile(node);
         assertOutWithMetadata("/**\n" +
-        		" * foo.bar.baz.A\n" +
-        		" *\n" +
-        		" * @fileoverview\n" +
-        		" *\n" +
-        		" * @suppress {checkTypes|accessControls}\n" +
-        		" */\n" +
-        		"\n" +
-        		"goog.provide('foo.bar.baz.A');\n" +
-        		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * @constructor\n" +
-        		" */\n" +
-        		"foo.bar.baz.A = function() {\n" +
-        		"};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * @export\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.prototype.foo = function() {\n};\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Metadata\n" +
-        		" *\n" +
-        		" * @type {Object.<string, Array.<Object>>}\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
-        		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Reflection\n" +
-        		" *\n" +
-        		" * @return {Object.<string, Function>}\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-        		"  return {\n" +
+				" * foo.bar.baz.A\n" +
+				" *\n" +
+				" * @fileoverview\n" +
+				" *\n" +
+				" * @suppress {checkTypes|accessControls}\n" +
+				" */\n" +
+				"\n" +
+				"goog.provide('foo.bar.baz.A');\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @constructor\n" +
+				" */\n" +
+				"foo.bar.baz.A = function() {\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @export\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.foo = function() {\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Metadata\n" +
+				" *\n" +
+				" * @type {Object.<string, Array.<Object>>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
 				"    variables: function () {return {};},\n" +
 				"    accessors: function () {return {};},\n" +
-        		"    methods: function () {\n" +
-        		"      return {\n" +
-        		"        'A': { type: '', declaredBy: 'foo.bar.baz.A'},\n" +
-        		"        'foo': { type: '', declaredBy: 'foo.bar.baz.A', metadata: function () { return [ { name: 'Before' } ]; }}\n" +
-        		"      };\n" +
-        		"    },\n" +
-        		"    metadata: function () { return [ { name: 'Event', args: [ { key: 'name', value: 'add' }, { key: 'type', value: 'mx.events.FlexEvent' } ] } ]; }\n" +
-        		"  };\n" +
-        		"};\n" +
-        		"goog.exportProperty(foo.bar.baz.A.prototype, 'foo', foo.bar.baz.A.prototype.foo);\n");
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'A': { type: '', declaredBy: 'foo.bar.baz.A'},\n" +
+				"        'foo': { type: '', declaredBy: 'foo.bar.baz.A', metadata: function () { return [ { name: 'Before' } ]; }}\n" +
+				"      };\n" +
+				"    },\n" +
+				"    metadata: function () { return [ { name: 'Event', args: [ { key: 'name', value: 'add' }, { key: 'type', value: 'mx.events.FlexEvent' } ] } ]; }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n" +
+				"goog.exportProperty(foo.bar.baz.A.prototype, 'foo', foo.bar.baz.A.prototype.foo);\n" );
     }
 
     @Test
@@ -390,86 +453,111 @@
         							  "}");
         asBlockWalker.visitFile(node);
         assertOutWithMetadata("/**\n" +
-        		  " * foo.bar.baz.A\n" +
-        		  " *\n" +
-        		  " * @fileoverview\n" +
-        		  " *\n" +
-        		  " * @suppress {checkTypes|accessControls}\n" +
-        		  " */\n" +
-        		  "\n" +
-        		  "goog.provide('foo.bar.baz.A');\n" +
-        		  "goog.provide('foo.bar.baz.A.InternalClass');\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * @constructor\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A = function() {\n" +
-        		  "  var /** @type {foo.bar.baz.A.InternalClass} */ internalClass = new foo.bar.baz.A.InternalClass();\n" +
-        		  "};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
-        		  "\n" +
-        		  "\n/" +
-        		  "**\n" +
-        		  " * Metadata\n" +
-        		  " *\n" +
-        		  " * @type {Object.<string, Array.<Object>>}\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
-          		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Reflection\n" +
-        		" *\n" +
-        		" * @return {Object.<string, Function>}\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-        		"  return {\n" +
+				" * foo.bar.baz.A\n" +
+				" *\n" +
+				" * @fileoverview\n" +
+				" *\n" +
+				" * @suppress {checkTypes|accessControls}\n" +
+				" */\n" +
+				"\n" +
+				"goog.provide('foo.bar.baz.A');\n" +
+				"goog.provide('foo.bar.baz.A.InternalClass');\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @constructor\n" +
+				" */\n" +
+				"foo.bar.baz.A = function() {\n" +
+				"  var /** @type {foo.bar.baz.A.InternalClass} */ internalClass = new foo.bar.baz.A.InternalClass();\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Metadata\n" +
+				" *\n" +
+				" * @type {Object.<string, Array.<Object>>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
 				"    variables: function () {return {};},\n" +
 				"    accessors: function () {return {};},\n" +
-        		"    methods: function () {\n" +
-        		"      return {\n" +
-        		"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
-        		"      };\n" +
-        		"    }\n" +
-        		"  };\n" +
-        		"};\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * @constructor\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.InternalClass = function() {\n" +
-        		  "};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.baz.A.InternalClass', foo.bar.baz.A.InternalClass);\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * Metadata\n" +
-        		  " *\n" +
-        		  " * @type {Object.<string, Array.<Object>>}\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' }] };\n" +
-          		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Reflection\n" +
-        		" *\n" +
-        		" * @return {Object.<string, Function>}\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-        		"  return {\n" +
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
+				"      };\n" +
+				"    }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @constructor\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass = function() {\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.baz.A.InternalClass', foo.bar.baz.A.InternalClass);\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Metadata\n" +
+				" *\n" +
+				" * @type {Object.<string, Array.<Object>>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' }] };\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
 				"    variables: function () {return {};},\n" +
 				"    accessors: function () {return {};},\n" +
-        		"    methods: function () {\n" +
-        		"      return {\n" +
-        		"        'InternalClass': { type: '', declaredBy: 'foo.bar.baz.A.InternalClass'}\n" +
-        		"      };\n" +
-        		"    }\n" +
-        		"  };\n" +
-        		"};\n");
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'InternalClass': { type: '', declaredBy: 'foo.bar.baz.A.InternalClass'}\n" +
+				"      };\n" +
+				"    }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n"
+		);
     }
 
 	@Test
@@ -500,34 +588,46 @@
 				" */\n" +
 				"foo.bar.baz.A = function() {\n" +
 				"  foo.bar.baz.A.internalFunction();\n" +
-				"};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+				"};\n" +
 				"\n" +
-				"\n/" +
-				"**\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
 				" * Metadata\n" +
 				" *\n" +
 				" * @type {Object.<string, Array.<Object>>}\n" +
 				" */\n" +
 				"foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
-          		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Reflection\n" +
-        		" *\n" +
-        		" * @return {Object.<string, Function>}\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-        		"  return {\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
 				"    variables: function () {return {};},\n" +
 				"    accessors: function () {return {};},\n" +
-        		"    methods: function () {\n" +
-        		"      return {\n" +
-        		"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
-        		"      };\n" +
-        		"    }\n" +
-        		"  };\n" +
-        		"};\n" +
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
+				"      };\n" +
+				"    }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n" +
 				"\n" +
 				"\n" +
 				"\n" +
@@ -563,34 +663,46 @@
 				" */\n" +
 				"foo.bar.baz.A = function() {\n" +
 				"  foo.bar.baz.A.internalVar = 3;\n" +
-				"};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+				"};\n" +
 				"\n" +
-				"\n/" +
-				"**\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
 				" * Metadata\n" +
 				" *\n" +
 				" * @type {Object.<string, Array.<Object>>}\n" +
 				" */\n" +
 				"foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
-          		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Reflection\n" +
-        		" *\n" +
-        		" * @return {Object.<string, Function>}\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-        		"  return {\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
 				"    variables: function () {return {};},\n" +
 				"    accessors: function () {return {};},\n" +
-        		"    methods: function () {\n" +
-        		"      return {\n" +
-        		"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
-        		"      };\n" +
-        		"    }\n" +
-        		"  };\n" +
-        		"};\n" +
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
+				"      };\n" +
+				"    }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n" +
 				"\n" +
 				"\n" +
 				"\n" +
@@ -598,7 +710,8 @@
 				" * @export\n" +
 				" * @type {number}\n" +
 				" */\n" +
-				"foo.bar.baz.A.internalVar = 2");
+				"foo.bar.baz.A.internalVar = 2"
+		);
 	}
 
     @Test
@@ -621,120 +734,152 @@
         							  "}");
         asBlockWalker.visitFile(node);
         assertOutWithMetadata("/**\n" +
-        		  " * foo.bar.baz.A\n" +
-        		  " *\n" +
-        		  " * @fileoverview\n" +
-        		  " *\n" +
-        		  " * @suppress {checkTypes|accessControls}\n" +
-        		  " */\n" +
-        		  "\n" +
-        		  "goog.provide('foo.bar.baz.A');\n" +
-        		  "goog.provide('foo.bar.baz.A.InternalClass');\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * @constructor\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A = function() {\n" +
-        		  "  var /** @type {foo.bar.baz.A.InternalClass} */ internalClass = new foo.bar.baz.A.InternalClass();\n" +
-        		  "  var /** @type {string} */ myString = foo.bar.baz.A.InternalClass.someString;\n" +
-        		  "  myString = foo.bar.baz.A.InternalClass.someStaticFunction();\n" +
-        		  "  myString = internalClass.someMethod();\n" +
-        		  "};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * Metadata\n" +
-        		  " *\n" +
-        		  " * @type {Object.<string, Array.<Object>>}\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
-            		"\n" +
-            		"\n" +
-            		"\n" +
-            		"/**\n" +
-            		" * Reflection\n" +
-            		" *\n" +
-            		" * @return {Object.<string, Function>}\n" +
-            		" */\n" +
-            		"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-            		"  return {\n" +
-					"    variables: function () {return {};},\n" +
-					"    accessors: function () {return {};},\n" +
-            		"    methods: function () {\n" +
-            		"      return {\n" +
-            		"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
-            		"      };\n" +
-            		"    }\n" +
-            		"  };\n" +
-            		"};\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * @constructor\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.InternalClass = function() {\n" +
-        		  "};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.baz.A.InternalClass', foo.bar.baz.A.InternalClass);\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * @export\n" +
-        		  " * @type {string}\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.InternalClass.someString = \"foo\";\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * @export\n" +
-        		  " * @return {string}\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.InternalClass.someStaticFunction = function() {\n" +
-        		  "  return \"bar\";\n" +
-        		  "};\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * @export\n" +
-        		  " * @return {string}\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.InternalClass.prototype.someMethod = function() {\n" +
-        		  "  return \"baz\";\n" +
-        		  "};\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * Metadata\n" +
-        		  " *\n" +
-        		  " * @type {Object.<string, Array.<Object>>}\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' }] };\n" +
-          		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Reflection\n" +
-        		" *\n" +
-        		" * @return {Object.<string, Function>}\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-        		"  return {\n" +
+				" * foo.bar.baz.A\n" +
+				" *\n" +
+				" * @fileoverview\n" +
+				" *\n" +
+				" * @suppress {checkTypes|accessControls}\n" +
+				" */\n" +
+				"\n" +
+				"goog.provide('foo.bar.baz.A');\n" +
+				"goog.provide('foo.bar.baz.A.InternalClass');\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @constructor\n" +
+				" */\n" +
+				"foo.bar.baz.A = function() {\n" +
+				"  var /** @type {foo.bar.baz.A.InternalClass} */ internalClass = new foo.bar.baz.A.InternalClass();\n" +
+				"  var /** @type {string} */ myString = foo.bar.baz.A.InternalClass.someString;\n" +
+				"  myString = foo.bar.baz.A.InternalClass.someStaticFunction();\n" +
+				"  myString = internalClass.someMethod();\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Metadata\n" +
+				" *\n" +
+				" * @type {Object.<string, Array.<Object>>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
+				"    variables: function () {return {};},\n" +
+				"    accessors: function () {return {};},\n" +
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
+				"      };\n" +
+				"    }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @constructor\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass = function() {\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.baz.A.InternalClass', foo.bar.baz.A.InternalClass);\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @type {string}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.someString = \"foo\";\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @return {string}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.someStaticFunction = function() {\n" +
+				"  return \"bar\";\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @return {string}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.prototype.someMethod = function() {\n" +
+				"  return \"baz\";\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Metadata\n" +
+				" *\n" +
+				" * @type {Object.<string, Array.<Object>>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' }] };\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
 				"    variables: function () {\n" +
 				"      return {\n" +
-				"        '|someString': { type: 'String'}\n" +
+				"        '|someString': { type: 'String', get_set: function (/** * */ v) {return v !== undefined ? foo.bar.baz.A.InternalClass.someString = v : foo.bar.baz.A.InternalClass.someString;}}\n" +
 				"      };\n" +
 				"    },\n" +
 				"    accessors: function () {return {};},\n" +
-        		"    methods: function () {\n" +
-        		"      return {\n" +
-        		"        'InternalClass': { type: '', declaredBy: 'foo.bar.baz.A.InternalClass'},\n" +
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'InternalClass': { type: '', declaredBy: 'foo.bar.baz.A.InternalClass'},\n" +
 				"        '|someStaticFunction': { type: 'String', declaredBy: 'foo.bar.baz.A.InternalClass'},\n" +
-        		"        'someMethod': { type: 'String', declaredBy: 'foo.bar.baz.A.InternalClass'}\n" +
-        		"      };\n" +
-        		"    }\n" +
-        		"  };\n" +
-        		"};\n");
+				"        'someMethod': { type: 'String', declaredBy: 'foo.bar.baz.A.InternalClass'}\n" +
+				"      };\n" +
+				"    }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n" +
+				"/**\n" +
+				" * Provide reflection support for distinguishing dynamic fields on class object (static)\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {Array<string>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO.statics = Object.keys(foo.bar.baz.A.InternalClass);\n"
+		);
     }
 
     @Test
@@ -762,130 +907,159 @@
         							  "}");
         asBlockWalker.visitFile(node);
         assertOutWithMetadata("/**\n" +
-        		  " * foo.bar.baz.A\n" +
-        		  " *\n" +
-        		  " * @fileoverview\n" +
-        		  " *\n" +
-        		  " * @suppress {checkTypes|accessControls}\n" +
-        		  " */\n" +
-        		  "\n" +
-        		  "goog.provide('foo.bar.baz.A');\n" +
-        		  "goog.provide('foo.bar.baz.A.InternalClass');\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * @constructor\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A = function() {\n" +
-        		  "  var /** @type {foo.bar.baz.A.InternalClass} */ internalClass = new foo.bar.baz.A.InternalClass();\n" +
-        		  "  this.myString = internalClass.someString;\n" +
-        		  "  internalClass.someString = this.myString;\n" +
-        		  "};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
-        		  "\n" +
-        		  "\n" +
-                  "foo.bar.baz.A.prototype.get__myString = function() {\n" +
-                  "  return null;\n" +
-                  "};\n" +
-        		  "\n" +
-        		  "\n" +
-                  "foo.bar.baz.A.prototype.set__myString = function(value) {\n" +
-                  "};\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "Object.defineProperties(foo.bar.baz.A.prototype, /** @lends {foo.bar.baz.A.prototype} */ {\n" +
-                  "/**\n  * @export\n  * @type {string} */\n" +
-                  "myString: {\n" +
-                  "get: foo.bar.baz.A.prototype.get__myString,\n" +
-                  "set: foo.bar.baz.A.prototype.set__myString}}\n" +
-                  ");\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * Metadata\n" +
-        		  " *\n" +
-        		  " * @type {Object.<string, Array.<Object>>}\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
-            		"\n" +
-            		"\n" +
-            		"\n" +
-            		"/**\n" +
-            		" * Reflection\n" +
-            		" *\n" +
-            		" * @return {Object.<string, Function>}\n" +
-            		" */\n" +
-            		"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-            		"  return {\n" +
-					"    variables: function () {return {};},\n" +
-            		"    accessors: function () {\n" +
-            		"      return {\n" +
-            		"        'myString': { type: 'String', access: 'readwrite', declaredBy: 'foo.bar.baz.A'}\n" +
-            		"      };\n" +
-            		"    },\n" +
-            		"    methods: function () {\n" +
-            		"      return {\n" +
-            		"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
-            		"      };\n" +
-            		"    }\n" +
-            		"  };\n" +
-            		"};\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * @constructor\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.InternalClass = function() {\n" +
-        		  "};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.baz.A.InternalClass', foo.bar.baz.A.InternalClass);\n" +
-        		  "\n" +
-        		  "\n" +
-                  "foo.bar.baz.A.InternalClass.prototype.get__someString = function() {\n" +
-                  "  return null;\n" +
-                  "};\n" +
-        		  "\n" +
-        		  "\n" +
-                  "foo.bar.baz.A.InternalClass.prototype.set__someString = function(value) {\n" +
-                  "};\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "Object.defineProperties(foo.bar.baz.A.InternalClass.prototype, /** @lends {foo.bar.baz.A.InternalClass.prototype} */ {\n" +
-                  "/**\n  * @export\n  * @type {string} */\n" +
-                  "someString: {\n" +
-                  "get: foo.bar.baz.A.InternalClass.prototype.get__someString,\n" +
-                  "set: foo.bar.baz.A.InternalClass.prototype.set__someString}}\n" +
-                  ");\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * Metadata\n" +
-        		  " *\n" +
-        		  " * @type {Object.<string, Array.<Object>>}\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' }] };\n" +
-          		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Reflection\n" +
-        		" *\n" +
-        		" * @return {Object.<string, Function>}\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-        		"  return {\n" +
+				" * foo.bar.baz.A\n" +
+				" *\n" +
+				" * @fileoverview\n" +
+				" *\n" +
+				" * @suppress {checkTypes|accessControls}\n" +
+				" */\n" +
+				"\n" +
+				"goog.provide('foo.bar.baz.A');\n" +
+				"goog.provide('foo.bar.baz.A.InternalClass');\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @constructor\n" +
+				" */\n" +
+				"foo.bar.baz.A = function() {\n" +
+				"  var /** @type {foo.bar.baz.A.InternalClass} */ internalClass = new foo.bar.baz.A.InternalClass();\n" +
+				"  this.myString = internalClass.someString;\n" +
+				"  internalClass.someString = this.myString;\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+				"\n" +
+				"\n" +
+				"foo.bar.baz.A.prototype.get__myString = function() {\n" +
+				"  return null;\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"foo.bar.baz.A.prototype.set__myString = function(value) {\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"Object.defineProperties(foo.bar.baz.A.prototype, /** @lends {foo.bar.baz.A.prototype} */ {\n" +
+				"/**\n" +
+				"  * @export\n" +
+				"  * @type {string} */\n" +
+				"myString: {\n" +
+				"get: foo.bar.baz.A.prototype.get__myString,\n" +
+				"set: foo.bar.baz.A.prototype.set__myString}}\n" +
+				");\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Metadata\n" +
+				" *\n" +
+				" * @type {Object.<string, Array.<Object>>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
 				"    variables: function () {return {};},\n" +
-        		"    accessors: function () {\n" +
-        		"      return {\n" +
-        		"        'someString': { type: 'String', access: 'readwrite', declaredBy: 'foo.bar.baz.A.InternalClass'}\n" +
-        		"      };\n" +
-        		"    },\n" +
-        		"    methods: function () {\n" +
-        		"      return {\n" +
-        		"        'InternalClass': { type: '', declaredBy: 'foo.bar.baz.A.InternalClass'}\n" +
-        		"      };\n" +
-        		"    }\n" +
-        		"  };\n" +
-        		"};\n");
+				"    accessors: function () {\n" +
+				"      return {\n" +
+				"        'myString': { type: 'String', access: 'readwrite', declaredBy: 'foo.bar.baz.A'}\n" +
+				"      };\n" +
+				"    },\n" +
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
+				"      };\n" +
+				"    }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @constructor\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass = function() {\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.baz.A.InternalClass', foo.bar.baz.A.InternalClass);\n" +
+				"\n" +
+				"\n" +
+				"foo.bar.baz.A.InternalClass.prototype.get__someString = function() {\n" +
+				"  return null;\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"foo.bar.baz.A.InternalClass.prototype.set__someString = function(value) {\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"Object.defineProperties(foo.bar.baz.A.InternalClass.prototype, /** @lends {foo.bar.baz.A.InternalClass.prototype} */ {\n" +
+				"/**\n" +
+				"  * @export\n" +
+				"  * @type {string} */\n" +
+				"someString: {\n" +
+				"get: foo.bar.baz.A.InternalClass.prototype.get__someString,\n" +
+				"set: foo.bar.baz.A.InternalClass.prototype.set__someString}}\n" +
+				");\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Metadata\n" +
+				" *\n" +
+				" * @type {Object.<string, Array.<Object>>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' }] };\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
+				"    variables: function () {return {};},\n" +
+				"    accessors: function () {\n" +
+				"      return {\n" +
+				"        'someString': { type: 'String', access: 'readwrite', declaredBy: 'foo.bar.baz.A.InternalClass'}\n" +
+				"      };\n" +
+				"    },\n" +
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'InternalClass': { type: '', declaredBy: 'foo.bar.baz.A.InternalClass'}\n" +
+				"      };\n" +
+				"    }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n"
+		);
     }
 
     @Test
@@ -908,140 +1082,178 @@
         							  "}");
         asBlockWalker.visitFile(node);
         assertOutWithMetadata("/**\n" +
-        		  " * foo.bar.baz.A\n" +
-        		  " *\n" +
-        		  " * @fileoverview\n" +
-        		  " *\n" +
-        		  " * @suppress {checkTypes|accessControls}\n" +
-        		  " */\n" +
-        		  "\n" +
-        		  "goog.provide('foo.bar.baz.A');\n" +
-        		  "goog.provide('foo.bar.baz.A.ITestInterface');\n" +
-        		  "goog.provide('foo.bar.baz.A.InternalClass');\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * @constructor\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A = function() {\n" +
-        		  "  var /** @type {foo.bar.baz.A.ITestInterface} */ internalClass = org.apache.royale.utils.Language.as(new foo.bar.baz.A.InternalClass(), foo.bar.baz.A.ITestInterface);\n" +
-        		  "  internalClass.test();\n" +
-        		  "};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * Metadata\n" +
-        		  " *\n" +
-        		  " * @type {Object.<string, Array.<Object>>}\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
-            		"\n" +
-            		"\n" +
-            		"\n" +
-            		"/**\n" +
-            		" * Reflection\n" +
-            		" *\n" +
-            		" * @return {Object.<string, Function>}\n" +
-            		" */\n" +
-            		"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-            		"  return {\n" +
-					"    variables: function () {return {};},\n" +
-					"    accessors: function () {return {};},\n" +
-            		"    methods: function () {\n" +
-            		"      return {\n" +
-            		"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
-            		"      };\n" +
-            		"    }\n" +
-            		"  };\n" +
-            		"};\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * @interface\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.ITestInterface = function() {\n" +
-        		  "};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.baz.A.ITestInterface', foo.bar.baz.A.ITestInterface);\n" +
-        		  "foo.bar.baz.A.ITestInterface.prototype.test = function() {\n" +
-        		  "};\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * Metadata\n" +
-        		  " *\n" +
-        		  " * @type {Object.<string, Array.<Object>>}\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.ITestInterface.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'ITestInterface', qName: 'foo.bar.baz.A.ITestInterface', kind: 'interface' }] };\n" +
+				" * foo.bar.baz.A\n" +
+				" *\n" +
+				" * @fileoverview\n" +
+				" *\n" +
+				" * @suppress {checkTypes|accessControls}\n" +
+				" */\n" +
+				"\n" +
+				"goog.provide('foo.bar.baz.A');\n" +
+				"goog.provide('foo.bar.baz.A.ITestInterface');\n" +
+				"goog.provide('foo.bar.baz.A.InternalClass');\n" +
 				"\n" +
 				"\n" +
 				"\n" +
-        		"/**\n" +
-        		" * Reflection\n" +
-        		" *\n" +
-        		" * @return {Object.<string, Function>}\n" +
-        		" */\n" +
-        		"foo.bar.baz.A.ITestInterface.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-        		"  return {\n" +
+				"/**\n" +
+				" * @constructor\n" +
+				" */\n" +
+				"foo.bar.baz.A = function() {\n" +
+				"  var /** @type {foo.bar.baz.A.ITestInterface} */ internalClass = org.apache.royale.utils.Language.as(new foo.bar.baz.A.InternalClass(), foo.bar.baz.A.ITestInterface);\n" +
+				"  internalClass.test();\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Metadata\n" +
+				" *\n" +
+				" * @type {Object.<string, Array.<Object>>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
+				"    variables: function () {return {};},\n" +
 				"    accessors: function () {return {};},\n" +
-        		"    methods: function () {\n" +
-        		"      return {\n" +
-        		"        'test': { type: 'void', declaredBy: 'foo.bar.baz.A.ITestInterface'}\n" +
-        		"      };\n" +
-        		"    }\n" +
-        		"  };\n" +
-        		"};\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * @constructor\n" +
-        		  " * @implements {foo.bar.baz.A.ITestInterface}\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.InternalClass = function() {\n" +
-        		  "};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.baz.A.InternalClass', foo.bar.baz.A.InternalClass);\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * @export\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.InternalClass.prototype.test = function() {\n" +
-        		  "};\n" +
-        		  "\n" +
-        		  "\n" +
-        		  "/**\n" +
-        		  " * Metadata\n" +
-        		  " *\n" +
-        		  " * @type {Object.<string, Array.<Object>>}\n" +
-        		  " */\n" +
-        		  "foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' }], interfaces: [foo.bar.baz.A.ITestInterface] };\n" +
-            		"\n" +
-            		"\n" +
-            		"\n" +
-            		"/**\n" +
-            		" * Reflection\n" +
-            		" *\n" +
-            		" * @return {Object.<string, Function>}\n" +
-            		" */\n" +
-            		"foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-            		"  return {\n" +
-					"    variables: function () {return {};},\n" +
-					"    accessors: function () {return {};},\n" +
-            		"    methods: function () {\n" +
-            		"      return {\n" +
-            		"        'InternalClass': { type: '', declaredBy: 'foo.bar.baz.A.InternalClass'},\n" +
-            		"        'test': { type: 'void', declaredBy: 'foo.bar.baz.A.InternalClass'}\n" +
-            		"      };\n" +
-            		"    }\n" +
-            		"  };\n" +
-            		"};\n"
-        		  );
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
+				"      };\n" +
+				"    }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @interface\n" +
+				" */\n" +
+				"foo.bar.baz.A.ITestInterface = function() {\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.baz.A.ITestInterface', foo.bar.baz.A.ITestInterface);\n" +
+				"foo.bar.baz.A.ITestInterface.prototype.test = function() {\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Metadata\n" +
+				" *\n" +
+				" * @type {Object.<string, Array.<Object>>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.ITestInterface.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'ITestInterface', qName: 'foo.bar.baz.A.ITestInterface', kind: 'interface' }] };\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.ITestInterface.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
+				"    accessors: function () {return {};},\n" +
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'test': { type: 'void', declaredBy: 'foo.bar.baz.A.ITestInterface'}\n" +
+				"      };\n" +
+				"    }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.ITestInterface.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @constructor\n" +
+				" * @implements {foo.bar.baz.A.ITestInterface}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass = function() {\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.baz.A.InternalClass', foo.bar.baz.A.InternalClass);\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * @export\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.prototype.test = function() {\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Metadata\n" +
+				" *\n" +
+				" * @type {Object.<string, Array.<Object>>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' }], interfaces: [foo.bar.baz.A.ITestInterface] };\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
+				"    variables: function () {return {};},\n" +
+				"    accessors: function () {return {};},\n" +
+				"    methods: function () {\n" +
+				"      return {\n" +
+				"        'InternalClass': { type: '', declaredBy: 'foo.bar.baz.A.InternalClass'},\n" +
+				"        'test': { type: 'void', declaredBy: 'foo.bar.baz.A.InternalClass'}\n" +
+				"      };\n" +
+				"    }\n" +
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n"
+		);
     }
 
 	@Test
 	public void testPackageQualified_ClassAndInternalStaticConst()
 	{
 		IFileNode node = compileAS("package foo.bar {\n" +
+				//adding an unneeded import node here exposed a failing test at one point:
+				"import foo.bar.*\n" +
 				"public function A():Number {\n" +
 				"    return Internal.x;\n" +
 				"}}\n" +
@@ -1075,7 +1287,13 @@
 				" * @constructor\n" +
 				" */\n" +
 				"foo.bar.A.Internal = function() {\n" +
-				"};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('foo.bar.A.Internal', foo.bar.A.Internal);\n" +
+				"};\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Prevent renaming of class. Needed for reflection.\n" +
+				" */\n" +
+				"goog.exportSymbol('foo.bar.A.Internal', foo.bar.A.Internal);\n" +
 				"\n" +
 				"\n" +
 				"/**\n" +
@@ -1092,21 +1310,35 @@
 				" * @type {Object.<string, Array.<Object>>}\n" +
 				" */\n" +
 				"foo.bar.A.Internal.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'Internal', qName: 'foo.bar.A.Internal', kind: 'class' }] };\n" +
-          		"\n" +
-        		"\n" +
-        		"\n" +
-        		"/**\n" +
-        		" * Reflection\n" +
-        		" *\n" +
-        		" * @return {Object.<string, Function>}\n" +
-        		" */\n" +
-        		"foo.bar.A.Internal.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
-        		"  return {\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"/**\n" +
+				" * Reflection\n" +
+				" *\n" +
+				" * @return {Object.<string, Function>}\n" +
+				" */\n" +
+				"foo.bar.A.Internal.prototype.ROYALE_REFLECTION_INFO = function () {\n" +
+				"  return {\n" +
 				"    variables: function () {return {};},\n" +
 				"    accessors: function () {return {};},\n" +
 				"    methods: function () {return {};}\n" +
-        		"  };\n" +
-        		"};\n");
+				"  };\n" +
+				"};\n" +
+				"/**\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {number}\n" +
+				" */\n" +
+				"foo.bar.A.Internal.prototype.ROYALE_REFLECTION_INFO.compileFlags = 15;\n" +
+				"/**\n" +
+				" * Provide reflection support for distinguishing dynamic fields on class object (static)\n" +
+				" * @export\n" +
+				" * @const\n" +
+				" * @type {Array<string>}\n" +
+				" */\n" +
+				"foo.bar.A.Internal.prototype.ROYALE_REFLECTION_INFO.statics = Object.keys(foo.bar.A.Internal);\n"
+		);
 	}
 	
 	@Test
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleStatements.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleStatements.java
index c1c0137..d71b6d6 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleStatements.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleStatements.java
@@ -21,11 +21,13 @@
 
 import org.apache.royale.compiler.driver.IBackend;
 import org.apache.royale.compiler.internal.codegen.js.goog.TestGoogStatements;
+import org.apache.royale.compiler.internal.driver.js.goog.JSGoogConfiguration;
 import org.apache.royale.compiler.internal.driver.js.royale.RoyaleBackend;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
 import org.apache.royale.compiler.internal.tree.as.LabeledStatementNode;
 import org.apache.royale.compiler.tree.as.IFileNode;
 import org.apache.royale.compiler.tree.as.IForLoopNode;
+import org.apache.royale.compiler.tree.as.IFunctionNode;
 import org.apache.royale.compiler.tree.as.IIfNode;
 import org.apache.royale.compiler.tree.as.IImportNode;
 import org.apache.royale.compiler.tree.as.ILiteralNode;
@@ -47,6 +49,7 @@
     {
         backend = createBackend();
         project = new RoyaleJSProject(workspace, backend);
+        project.config = new JSGoogConfiguration();
         super.setUp();
     }
     
@@ -90,10 +93,181 @@
     @Test
     public void testVarDeclaration_withType()
     {
-        IVariableNode node = (IVariableNode) getNode("var a:int;",
+        IFunctionNode node = (IFunctionNode) getNode("var a:int;",
+            IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("RoyaleTest_A.prototype.royaleTest_a = function() {\n  var /** @type {number} */ a = 0;\n  //var /** @type {number} */ a = 0;\n}");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeBooleanAndAssignedPositiveNumber()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:Boolean = 123.4;",
                 IVariableNode.class);
         asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {number} */ a = 0");
+        assertOut("var /** @type {boolean} */ a = true");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeBooleanAndAssignedNegativeNumber()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:Boolean = -123;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {boolean} */ a = true");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeBooleanAndAssignedZeroNumber()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:Boolean = 0;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {boolean} */ a = false");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeBooleanAndAssignedDecimalNumber()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:Boolean = 0.123;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {boolean} */ a = true");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeBooleanAndAssignedNull()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:Boolean = null;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {boolean} */ a = false");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeBooleanAndAssignedUndefined()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:Boolean = undefined;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {boolean} */ a = false");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeIntAndAssignedHex()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:int = 0xabc;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {number} */ a = 0xabc");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeUintAndAssignedHex()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:uint = 0xabc;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {number} */ a = 0xabc");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeNumberAndAssignedHex()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:Number = 0xabc;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {number} */ a = 0xabc");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeIntAndAssignedNumber()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:int = 123.4;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {number} */ a = 123");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeUintAndAssignedNumber()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:uint = 123.4;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {number} */ a = 123");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeUintAndAssignedNegative()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:uint = -123;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {number} */ a = 4294967173");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeStringAndAssignedStringLiteral()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:String = \"hi\";",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {string} */ a = \"hi\"");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeStringAndAssignedNull()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:String = null;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {string} */ a = null");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeStringAndAssignedUndefined()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:String = undefined;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {string} */ a = null");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeStringAndAssignedStringVar()
+    {
+        IVariableNode node = (IVariableNode) getNode("function royaleTest_a():Object { var a:String = b }var b:String;",
+            IVariableNode.class, WRAP_LEVEL_CLASS);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {string} */ a = this.b");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeStringAndAssignedAnyTypeVar()
+    {
+        IVariableNode node = (IVariableNode) getNode("function royaleTest_a():Object { var a:String = b }var b:*;",
+            IVariableNode.class, WRAP_LEVEL_CLASS);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {string} */ a = org.apache.royale.utils.Language.string(this.b)");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeStringAndAssignedToStringFunctionCall()
+    {
+        IVariableNode node = (IVariableNode) getNode("function royaleTest_a():Object { var a:String = b.toString(); }var b:Object;",
+            IVariableNode.class, WRAP_LEVEL_CLASS);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {string} */ a = this.b.toString()");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeNumberAndAssignedDateProperty()
+    {
+        IVariableNode node = (IVariableNode) getNode("function royaleTest_a():Object { var a:Number = b.fullYear; }var b:Date;",
+            IVariableNode.class, WRAP_LEVEL_CLASS);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {number} */ a = this.b.getFullYear()");
     }
 
     //----------------------------------
@@ -546,11 +720,8 @@
         		              "RoyaleTest_A = function() {\n" +
         		              "};\n\n\n/**\n * Prevent renaming of class. Needed for reflection.\n */\ngoog.exportSymbol('RoyaleTest_A', RoyaleTest_A);\n\n\n" +
         		              "RoyaleTest_A.prototype.royaleTest_a = function() {\n" +
-        		              "  var self = this;\n" +
-        		              "  var /** @type {Function} */ __localFn0__ = function(foo, bar) {\n" +
-            		          "    bar = typeof bar !== 'undefined' ? bar : 'goo';\n" +
-            		          "    return -1;\n" +
-            		          "  }\n" +
+                              "  var self = this;\n" +
+                              "  var /** @type {number} */ len = 0;\n" +
             		          "  try {\n" +
         		              "    a;\n" +
         		              "  } catch (e) {\n" +
@@ -567,7 +738,7 @@
         		              "  } finally {\n" +
         		              "  }\n" +
         		              "  if (d) {\n" +
-        		              "    var /** @type {number} */ len = 0;\n" +
+        		              "    //var /** @type {number} */ len = 0;\n" +
         		              "    for (var /** @type {number} */ i = 0; i < len; i++)\n" +
         		              "      break;\n" +
         		              "  }\n" +
@@ -595,7 +766,10 @@
         		              "      }\n" +
         		              "    } finally {\n" +
         		              "      d;\n" +
-        		              "      var /** @type {Object} */ a = __localFn0__;\n" +
+        		              "      var /** @type {Object} */ a = function(foo, bar) {\n" +
+            		          "        bar = typeof bar !== 'undefined' ? bar : 'goo';\n" +
+            		          "        return -1;\n" +
+            		          "      };\n" +
         		              "      eee.dd;\n" +
         		              "      eee.dd;\n" +
         		              "      eee.dd;\n" +
@@ -628,7 +802,13 @@
                                 "  accessors: function () {return {};},\n" +
                                 "  methods: function () {return {};}\n" +
         		        		"};\n" +
-        		        		"};\n");
+                                "};\n" +
+                                "/**\n" +
+                                " * @export\n" +
+                                " * @const\n" +
+                                " * @type {number}\n" +
+                                " */\n" +
+                                "RoyaleTest_A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;\n");
     }
 
     @Override
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/sourcemaps/TestSourceMapExpressions.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/sourcemaps/TestSourceMapExpressions.java
index 72beed5..98978db 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/sourcemaps/TestSourceMapExpressions.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/sourcemaps/TestSourceMapExpressions.java
@@ -199,6 +199,36 @@
         assertMapping(node, 0, 4, 0, 4, 0, 5); // b
     }
 
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentLiteral()
+    {
+        IBinaryOperatorNode node = getBinaryNode("a = 123.2");
+        asBlockWalker.visitBinaryOperator(node);
+        assertMapping(node, 0, 0, 0, 0, 0, 1); // a
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // =
+        assertMapping(node, 0, 4, 0, 4, 0, 9); // 123.2
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentLiteralWithCompileTimeIntCoercion()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var a:int;a = 123.2");
+        asBlockWalker.visitBinaryOperator(node);
+        assertMapping(node, 0, 0, 0, 0, 0, 1); // a
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // =
+        assertMapping(node, 0, 4, 0, 4, 0, 7); // 123
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentLiteralWithCompileTimeUintCoercion()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var a:uint;a = -123");
+        asBlockWalker.visitBinaryOperator(node);
+        assertMapping(node, 0, 0, 0, 0, 0, 1); // a
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // =
+        assertMapping(node, 0, 4, 0, 4, 0, 14); // 4294967173
+    }
+
     //----------------------------------
     // Bitwise
     //----------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
index cca0683..d13a577 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
@@ -65,13 +65,13 @@
     @Test
     public void testVarDeclaration_withType()
     {
-        IVariableNode node = (IVariableNode) getNode("var a:int;",
+        IVariableNode node = (IVariableNode) getNode("var a:Number;",
                 IVariableNode.class);
         asBlockWalker.visitVariable(node);
         //var /** @type {number} */ a
         assertMapping(node, 0, 0, 0, 0, 0, 4);   // var
         assertMapping(node, 0, 4, 0, 26, 0, 27); // a
-        assertMapping(node, 0, 5, 0, 4, 0, 26);  // :int
+        assertMapping(node, 0, 5, 0, 4, 0, 26);  // :Number
     }
 
     @Test
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/TestMXMLApplication.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/TestMXMLApplication.java
index 0aa5601..0e39169 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/TestMXMLApplication.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/TestMXMLApplication.java
@@ -18,6 +18,8 @@
  */
 package org.apache.royale.compiler.internal.codegen.mxml;
 
+import static org.junit.Assert.assertNotNull;
+
 import org.apache.royale.compiler.internal.test.MXMLTestBase;
 import org.apache.royale.compiler.tree.mxml.IMXMLFileNode;
 import org.junit.Test;
@@ -33,6 +35,7 @@
                 + "</custom:TestInstance>";
 
         IMXMLFileNode node = compileMXML(code);
+        assertNotNull(node);
 
         mxmlBlockWalker.visitFile(node);
 
@@ -48,6 +51,7 @@
                 + "</custom:TestInstance>";
 
         IMXMLFileNode node = compileMXML(code);
+        assertNotNull(node);
 
         mxmlBlockWalker.visitFile(node);
 
@@ -64,6 +68,7 @@
                 + "</custom:TestInstance>";
 
         IMXMLFileNode node = compileMXML(code);
+        assertNotNull(node);
 
         mxmlBlockWalker.visitFile(node);
 
@@ -80,6 +85,7 @@
                 + "    ]]></fx:Script>" + "</custom:TestInstance>";
 
         IMXMLFileNode node = compileMXML(code);
+        assertNotNull(node);
 
         mxmlBlockWalker.visitFile(node);
 
@@ -99,6 +105,7 @@
                 + "    </fx:Declarations>" + "</custom:TestInstance>";
 
         IMXMLFileNode node = compileMXML(code);
+        assertNotNull(node);
 
         mxmlBlockWalker.visitFile(node);
 
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/royale/TestRoyaleMXMLApplication.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/royale/TestRoyaleMXMLApplication.java
index c5c3750..deec96c 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/royale/TestRoyaleMXMLApplication.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/royale/TestRoyaleMXMLApplication.java
@@ -19,6 +19,7 @@
 package org.apache.royale.compiler.internal.codegen.mxml.royale;
 
 import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThat;
 
 import org.apache.royale.compiler.clients.MXMLJSC;
@@ -57,11 +58,11 @@
 
         IMXMLFileNode node = compileMXML(fileName, true,
                 new File(testAdapter.getUnitTestBaseDir(), "royale/files").getPath(), false);
+		assertNotNull(node);
 
         mxmlBlockWalker.visitFile(node);
         
         JSCSSCompilationSession jscss = (JSCSSCompilationSession)project.getCSSCompilationSession();
-        jscss.setExcludeDefaultsCSSFiles(new ArrayList<String>());
 
         String result = getCodeFromFile("CSSTestSource_result.css", "royale/files");
         String output = jscss.emitCSS();       
@@ -80,6 +81,7 @@
 
         IMXMLFileNode node = compileMXML(fileName, true,
                 new File(testAdapter.getUnitTestBaseDir(), "royale/files").getPath(), false);
+		assertNotNull(node);
 
         mxmlBlockWalker.visitFile(node);
         
@@ -95,6 +97,7 @@
 
         IMXMLFileNode node = compileMXML(fileName, true,
                 new File(testAdapter.getUnitTestBaseDir(), "royale/files").getPath(), false);
+		assertNotNull(node);
 
         mxmlBlockWalker.visitFile(node);
 
@@ -110,6 +113,7 @@
 
         IMXMLFileNode node = compileMXML(fileName, true,
                 new File(testAdapter.getUnitTestBaseDir(), "royale/files").getPath(), false);
+		assertNotNull(node);
 
         mxmlBlockWalker.visitFile(node);
 
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/ASTestBase.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/ASTestBase.java
index fd484ba..807c950 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/ASTestBase.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/ASTestBase.java
@@ -58,6 +58,19 @@
     }
 
     @Override
+    protected void addDependencies()
+    {
+        if (libraries.size() == 0)
+        {
+        	String jsSwcPath = FilenameNormalization.normalize("../compiler-externc/target/js.swc");
+    		libraries.add(new File(jsSwcPath));
+        	String customSwcPath = FilenameNormalization.normalize("../compiler-jx/target/custom.swc");
+    		libraries.add(new File(customSwcPath));
+        }
+        super.addDependencies();
+    }
+
+    @Override
     protected void addSourcePaths(List<File> sourcePaths)
     {
         //sourcePaths.add(new File(FilenameNormalization.normalize(
@@ -194,4 +207,10 @@
         return (IVariableNode) getNode(code, IVariableNode.class);
     }
 
+    protected IASNode getLocalFunction(String code)
+    {
+        IFunctionNode method = (IFunctionNode) getNode(code, IFunctionNode.class);
+        return (IFunctionNode) findFirstDescendantOfType(method, IFunctionNode.class);
+    }
+
 }
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/MXMLTestBase.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/MXMLTestBase.java
index 5235ffc..7f8ba79 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/MXMLTestBase.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/MXMLTestBase.java
@@ -18,6 +18,8 @@
  */
 package org.apache.royale.compiler.internal.test;
 
+import static org.junit.Assert.assertNotNull;
+
 import java.io.File;
 import java.util.List;
 
@@ -54,6 +56,19 @@
     }
 
     @Override
+    protected void addDependencies()
+    {
+        if (libraries.size() == 0)
+        {
+        	String jsSwcPath = FilenameNormalization.normalize("../compiler-externc/target/js.swc");
+    		libraries.add(new File(jsSwcPath));
+        	String customSwcPath = FilenameNormalization.normalize("../compiler-jx/target/custom.swc");
+    		libraries.add(new File(customSwcPath));
+        }
+        super.addDependencies();
+    }
+
+    @Override
     protected void addLibraries(List<File> libraries)
     {
         //libraries.addAll(testAdapter.getLibraries(true));
@@ -103,6 +118,7 @@
                     + "</custom:TestInstance>";
 
         IMXMLFileNode node = compileMXML(code);
+        assertNotNull(node);
 
         if (wrapLevel >= WRAP_LEVEL_NODE) // for now: attributes
         {
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/RoyaleTestBase.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/RoyaleTestBase.java
index 67ef4fb..5f7a8bd 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/RoyaleTestBase.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/RoyaleTestBase.java
@@ -18,14 +18,14 @@
  */
 package org.apache.royale.compiler.internal.test;
 
+import static org.junit.Assert.assertNotNull;
+
 import java.io.File;
 import java.util.List;
 
 import org.apache.royale.compiler.driver.IBackend;
 import org.apache.royale.compiler.internal.driver.mxml.royale.MXMLRoyaleBackend;
-import org.apache.royale.compiler.internal.mxml.MXMLNamespaceMapping;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
-import org.apache.royale.compiler.mxml.IMXMLNamespaceMapping;
 import org.apache.royale.compiler.tree.as.IASNode;
 import org.apache.royale.compiler.tree.mxml.IMXMLFileNode;
 import org.apache.royale.compiler.tree.mxml.IMXMLNode;
@@ -100,6 +100,7 @@
                 + code + "]]></fx:Script></basic:Application>";
 
         IMXMLFileNode node = compileMXML(code);
+        assertNotNull(node);
 
         return findFirstASDescendantOfType(node, type);
     }
@@ -115,6 +116,7 @@
         }
 
         IMXMLFileNode node = compileMXML(code);
+        assertNotNull(node);
 
         return findFirstDescendantOfType(node, type);
     }
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/TestBase.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/TestBase.java
index 944b06e..c436fd9 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/TestBase.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/TestBase.java
@@ -20,7 +20,6 @@
 package org.apache.royale.compiler.internal.test;
 
 import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThat;
 
 import java.io.BufferedOutputStream;
@@ -47,6 +46,7 @@
 import org.apache.royale.compiler.config.Configurator;
 import org.apache.royale.compiler.driver.IBackend;
 import org.apache.royale.compiler.internal.codegen.as.ASFilterWriter;
+import org.apache.royale.compiler.internal.definitions.DefinitionBase;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
 import org.apache.royale.compiler.internal.projects.RoyaleProjectConfigurator;
 import org.apache.royale.compiler.internal.projects.ISourceFileHandler;
@@ -102,13 +102,15 @@
 
     protected File tempDir;
 
-    private List<File> sourcePaths = new ArrayList<File>();
-    private List<File> libraries = new ArrayList<File>();
-    private List<IMXMLNamespaceMapping> namespaceMappings = new ArrayList<IMXMLNamespaceMapping>();
+    protected List<File> sourcePaths = new ArrayList<File>();
+    protected List<File> libraries = new ArrayList<File>();
+    protected List<IMXMLNamespaceMapping> namespaceMappings = new ArrayList<IMXMLNamespaceMapping>();
 
     @Before
     public void setUp()
     {
+        DefinitionBase.setPerformanceCachingEnabled(true);
+
         errors = new ArrayList<ICompilerProblem>();
 
         if (project == null)
@@ -149,6 +151,7 @@
     @After
     public void tearDown()
     {
+        DefinitionBase.setPerformanceCachingEnabled(false);
         backend = null;
         writer = null;
     }
@@ -692,7 +695,7 @@
         	String jsSwcPath = FilenameNormalization.normalize("../compiler-externc/target/js.swc");
     		libraries.add(new File(jsSwcPath));
         	String customSwcPath = FilenameNormalization.normalize("../compiler/target/custom.swc");
-    		libraries.add(new File(customSwcPath));        	
+    		libraries.add(new File(customSwcPath));
         }
         addNamespaceMappings(namespaceMappings);
 
diff --git a/compiler-jx/src/test/resources/royale/projects/bad_overrides/Test_result.js b/compiler-jx/src/test/resources/royale/projects/bad_overrides/Test_result.js
index 23bd2a6..63b5209 100644
--- a/compiler-jx/src/test/resources/royale/projects/bad_overrides/Test_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/bad_overrides/Test_result.js
@@ -86,3 +86,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+Test.prototype.ROYALE_REFLECTION_INFO.compileFlags = 8;
diff --git a/compiler-jx/src/test/resources/royale/projects/bad_overrides/classes/A_result.js b/compiler-jx/src/test/resources/royale/projects/bad_overrides/classes/A_result.js
index ec11c7e..00a8df0 100644
--- a/compiler-jx/src/test/resources/royale/projects/bad_overrides/classes/A_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/bad_overrides/classes/A_result.js
@@ -86,3 +86,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+classes.A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 8;
diff --git a/compiler-jx/src/test/resources/royale/projects/bad_overrides/classes/B_result.js b/compiler-jx/src/test/resources/royale/projects/bad_overrides/classes/B_result.js
index d4a3f12..a0174ff 100644
--- a/compiler-jx/src/test/resources/royale/projects/bad_overrides/classes/B_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/bad_overrides/classes/B_result.js
@@ -61,3 +61,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+classes.B.prototype.ROYALE_REFLECTION_INFO.compileFlags = 8;
diff --git a/compiler-jx/src/test/resources/royale/projects/bad_overrides/classes/C_result.js b/compiler-jx/src/test/resources/royale/projects/bad_overrides/classes/C_result.js
index 0b1398e..4799d88 100644
--- a/compiler-jx/src/test/resources/royale/projects/bad_overrides/classes/C_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/bad_overrides/classes/C_result.js
@@ -61,3 +61,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+classes.C.prototype.ROYALE_REFLECTION_INFO.compileFlags = 8;
diff --git a/compiler-jx/src/test/resources/royale/projects/bad_overrides/interfaces/IA_result.js b/compiler-jx/src/test/resources/royale/projects/bad_overrides/interfaces/IA_result.js
index 395e896..878ead5 100644
--- a/compiler-jx/src/test/resources/royale/projects/bad_overrides/interfaces/IA_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/bad_overrides/interfaces/IA_result.js
@@ -68,3 +68,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+interfaces.IA.prototype.ROYALE_REFLECTION_INFO.compileFlags = 8;
diff --git a/compiler-jx/src/test/resources/royale/projects/bad_overrides/interfaces/IB_result.js b/compiler-jx/src/test/resources/royale/projects/bad_overrides/interfaces/IB_result.js
index e28bf2e..c70befd 100644
--- a/compiler-jx/src/test/resources/royale/projects/bad_overrides/interfaces/IB_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/bad_overrides/interfaces/IB_result.js
@@ -56,3 +56,9 @@
     methods: function () {return {};}
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+interfaces.IB.prototype.ROYALE_REFLECTION_INFO.compileFlags = 8;
diff --git a/compiler-jx/src/test/resources/royale/projects/bad_overrides/interfaces/IC_result.js b/compiler-jx/src/test/resources/royale/projects/bad_overrides/interfaces/IC_result.js
index cf0628d..db98f47 100644
--- a/compiler-jx/src/test/resources/royale/projects/bad_overrides/interfaces/IC_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/bad_overrides/interfaces/IC_result.js
@@ -56,3 +56,9 @@
     methods: function () {return {};}
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+interfaces.IC.prototype.ROYALE_REFLECTION_INFO.compileFlags = 8;
diff --git a/compiler-jx/src/test/resources/royale/projects/circular/Base_result.js b/compiler-jx/src/test/resources/royale/projects/circular/Base_result.js
index 1d27a23..ea802df 100644
--- a/compiler-jx/src/test/resources/royale/projects/circular/Base_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/circular/Base_result.js
@@ -66,3 +66,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+Base.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/circular/Super_result.js b/compiler-jx/src/test/resources/royale/projects/circular/Super_result.js
index 146ca29..60b608f 100644
--- a/compiler-jx/src/test/resources/royale/projects/circular/Super_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/circular/Super_result.js
@@ -42,7 +42,7 @@
  * @private
  * @type {Base}
  */
-Super.isItCircular;
+Super.isItCircular = null;
 
 
 /**
@@ -70,3 +70,16 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+Super.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
+/**
+ * Provide reflection support for distinguishing dynamic fields on class object (static)
+ * @export
+ * @const
+ * @type {Array<string>}
+ */
+Super.prototype.ROYALE_REFLECTION_INFO.statics = Object.keys(Super);
\ No newline at end of file
diff --git a/compiler-jx/src/test/resources/royale/projects/circular_proto/A_result.js b/compiler-jx/src/test/resources/royale/projects/circular_proto/A_result.js
index b2481e4..007efbf 100644
--- a/compiler-jx/src/test/resources/royale/projects/circular_proto/A_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/circular_proto/A_result.js
@@ -72,3 +72,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 8;
diff --git a/compiler-jx/src/test/resources/royale/projects/circular_proto/B_result.js b/compiler-jx/src/test/resources/royale/projects/circular_proto/B_result.js
index efacd72..8bafb82 100644
--- a/compiler-jx/src/test/resources/royale/projects/circular_proto/B_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/circular_proto/B_result.js
@@ -71,8 +71,14 @@
     methods: function () {
       return {
         'B': { type: '', declaredBy: 'B'},
-        '|a': { type: 'int', declaredBy: 'B', parameters: function () { return [  { index: 1, type: 'Boolean', optional: false } ]; }}
+        '|a': { type: 'int', declaredBy: 'B', parameters: function () { return [ { index: 1, type: 'Boolean', optional: false } ]; }}
       };
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+B.prototype.ROYALE_REFLECTION_INFO.compileFlags = 8;
diff --git a/compiler-jx/src/test/resources/royale/projects/circular_proto/C_result.js b/compiler-jx/src/test/resources/royale/projects/circular_proto/C_result.js
index e230054..30562a9 100644
--- a/compiler-jx/src/test/resources/royale/projects/circular_proto/C_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/circular_proto/C_result.js
@@ -73,8 +73,14 @@
     methods: function () {
       return {
         'C': { type: '', declaredBy: 'C'},
-        '|a': { type: 'int', declaredBy: 'C', parameters: function () { return [  { index: 1, type: 'Boolean', optional: false } ]; }}
+        '|a': { type: 'int', declaredBy: 'C', parameters: function () { return [ { index: 1, type: 'Boolean', optional: false } ]; }}
       };
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+C.prototype.ROYALE_REFLECTION_INFO.compileFlags = 8;
diff --git a/compiler-jx/src/test/resources/royale/projects/circular_proto/D_result.js b/compiler-jx/src/test/resources/royale/projects/circular_proto/D_result.js
index d3171dc..48d84c0 100644
--- a/compiler-jx/src/test/resources/royale/projects/circular_proto/D_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/circular_proto/D_result.js
@@ -73,8 +73,14 @@
     methods: function () {
       return {
         'D': { type: '', declaredBy: 'D'},
-        '|a': { type: 'int', declaredBy: 'D', parameters: function () { return [  { index: 1, type: 'Boolean', optional: false } ]; }}
+        '|a': { type: 'int', declaredBy: 'D', parameters: function () { return [ { index: 1, type: 'Boolean', optional: false } ]; }}
       };
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+D.prototype.ROYALE_REFLECTION_INFO.compileFlags = 8;
diff --git a/compiler-jx/src/test/resources/royale/projects/circular_proto/E_result.js b/compiler-jx/src/test/resources/royale/projects/circular_proto/E_result.js
index 9eb682c..04e154d 100644
--- a/compiler-jx/src/test/resources/royale/projects/circular_proto/E_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/circular_proto/E_result.js
@@ -69,8 +69,14 @@
     methods: function () {
       return {
         'E': { type: '', declaredBy: 'E'},
-        '|a': { type: 'int', declaredBy: 'E', parameters: function () { return [  { index: 1, type: 'Boolean', optional: false } ]; }}
+        '|a': { type: 'int', declaredBy: 'E', parameters: function () { return [ { index: 1, type: 'Boolean', optional: false } ]; }}
       };
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+E.prototype.ROYALE_REFLECTION_INFO.compileFlags = 8;
diff --git a/compiler-jx/src/test/resources/royale/projects/circular_proto/F_result.js b/compiler-jx/src/test/resources/royale/projects/circular_proto/F_result.js
index c641222..bb5bf9d 100644
--- a/compiler-jx/src/test/resources/royale/projects/circular_proto/F_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/circular_proto/F_result.js
@@ -73,8 +73,14 @@
     methods: function () {
       return {
         'F': { type: '', declaredBy: 'F'},
-        '|a': { type: 'int', declaredBy: 'F', parameters: function () { return [  { index: 1, type: 'Boolean', optional: false } ]; }}
+        '|a': { type: 'int', declaredBy: 'F', parameters: function () { return [ { index: 1, type: 'Boolean', optional: false } ]; }}
       };
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+F.prototype.ROYALE_REFLECTION_INFO.compileFlags = 8;
diff --git a/compiler-jx/src/test/resources/royale/projects/interfaces/Test_result.js b/compiler-jx/src/test/resources/royale/projects/interfaces/Test_result.js
index ffdd7be..41f6619 100644
--- a/compiler-jx/src/test/resources/royale/projects/interfaces/Test_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/interfaces/Test_result.js
@@ -82,8 +82,14 @@
     methods: function () {
       return {
         'Test': { type: '', declaredBy: 'Test'},
-        'doSomething': { type: 'interfaces.IC', declaredBy: 'Test', parameters: function () { return [  { index: 1, type: 'interfaces.IC', optional: false } ]; }}
+        'doSomething': { type: 'interfaces.IC', declaredBy: 'Test', parameters: function () { return [ { index: 1, type: 'interfaces.IC', optional: false } ]; }}
       };
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+Test.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/interfaces/classes/A_result.js b/compiler-jx/src/test/resources/royale/projects/interfaces/classes/A_result.js
index 5020237..38adfe9 100644
--- a/compiler-jx/src/test/resources/royale/projects/interfaces/classes/A_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/interfaces/classes/A_result.js
@@ -66,3 +66,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+classes.A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/interfaces/classes/B_result.js b/compiler-jx/src/test/resources/royale/projects/interfaces/classes/B_result.js
index d4a3f12..362c2ac 100644
--- a/compiler-jx/src/test/resources/royale/projects/interfaces/classes/B_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/interfaces/classes/B_result.js
@@ -61,3 +61,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+classes.B.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/interfaces/classes/C_result.js b/compiler-jx/src/test/resources/royale/projects/interfaces/classes/C_result.js
index 0b1398e..3a586f8 100644
--- a/compiler-jx/src/test/resources/royale/projects/interfaces/classes/C_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/interfaces/classes/C_result.js
@@ -61,3 +61,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+classes.C.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/IA_result.js b/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/IA_result.js
index 6b1a475..92fc242 100644
--- a/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/IA_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/IA_result.js
@@ -59,3 +59,9 @@
     methods: function () {return {};}
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+interfaces.IA.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/IC_result.js b/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/IC_result.js
index 465c89c..0aaf33e 100644
--- a/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/IC_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/IC_result.js
@@ -59,3 +59,9 @@
     methods: function () {return {};}
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+interfaces.IC.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/ID_result.js b/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/ID_result.js
index b86a0af..31223a4 100644
--- a/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/ID_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/ID_result.js
@@ -56,3 +56,9 @@
     methods: function () {return {};}
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+interfaces.ID.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/IE_result.js b/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/IE_result.js
index 239c8bd..d4f2f8f 100644
--- a/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/IE_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/interfaces/interfaces/IE_result.js
@@ -68,3 +68,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+interfaces.IE.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/internal/MainClass_result.js b/compiler-jx/src/test/resources/royale/projects/internal/MainClass_result.js
index 826e5f1..d403d5f 100644
--- a/compiler-jx/src/test/resources/royale/projects/internal/MainClass_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/internal/MainClass_result.js
@@ -64,6 +64,12 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+MainClass.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
 
 
 
@@ -85,7 +91,7 @@
  * @export
  * @type {OtherClass}
  */
-MainClass.InternalClass.prototype.foo;
+MainClass.InternalClass.prototype.foo = null;
 
 
 /**
@@ -106,7 +112,7 @@
   return {
     variables: function () {
       return {
-        'foo': { type: 'OtherClass'}
+        'foo': { type: 'OtherClass', get_set: function (/** MainClass.InternalClass */ inst, /** * */ v) {return v !== undefined ? inst.foo = v : inst.foo;}}
       };
     },
     accessors: function () {return {};},
@@ -117,3 +123,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+MainClass.InternalClass.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
\ No newline at end of file
diff --git a/compiler-jx/src/test/resources/royale/projects/internal/OtherClass_result.js b/compiler-jx/src/test/resources/royale/projects/internal/OtherClass_result.js
index 9506443..ad59e37 100644
--- a/compiler-jx/src/test/resources/royale/projects/internal/OtherClass_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/internal/OtherClass_result.js
@@ -61,3 +61,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+OtherClass.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/overrides/Test_result.js b/compiler-jx/src/test/resources/royale/projects/overrides/Test_result.js
index 5a0e4db..3d227df 100644
--- a/compiler-jx/src/test/resources/royale/projects/overrides/Test_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/overrides/Test_result.js
@@ -88,3 +88,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+Test.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/overrides/classes/A_result.js b/compiler-jx/src/test/resources/royale/projects/overrides/classes/A_result.js
index 65ede50..577dab8 100644
--- a/compiler-jx/src/test/resources/royale/projects/overrides/classes/A_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/overrides/classes/A_result.js
@@ -86,3 +86,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+classes.A.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/overrides/classes/B_result.js b/compiler-jx/src/test/resources/royale/projects/overrides/classes/B_result.js
index d4a3f12..362c2ac 100644
--- a/compiler-jx/src/test/resources/royale/projects/overrides/classes/B_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/overrides/classes/B_result.js
@@ -61,3 +61,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+classes.B.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/overrides/classes/C_result.js b/compiler-jx/src/test/resources/royale/projects/overrides/classes/C_result.js
index 0506eac..a8fa919 100644
--- a/compiler-jx/src/test/resources/royale/projects/overrides/classes/C_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/overrides/classes/C_result.js
@@ -66,3 +66,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+classes.C.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/overrides/interfaces/IA_result.js b/compiler-jx/src/test/resources/royale/projects/overrides/interfaces/IA_result.js
index 0a73f33..1a5b8ce 100644
--- a/compiler-jx/src/test/resources/royale/projects/overrides/interfaces/IA_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/overrides/interfaces/IA_result.js
@@ -38,11 +38,13 @@
  */
 goog.exportSymbol('interfaces.IA', interfaces.IA);
 /**
+ * @export
  * @return {classes.B}
  */
 interfaces.IA.prototype.someFunction = function() {
 };
 /**
+ * @export
  * @return {interfaces.IB}
  */
 interfaces.IA.prototype.someOtherFunction = function() {
@@ -74,3 +76,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+interfaces.IA.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/overrides/interfaces/IB_result.js b/compiler-jx/src/test/resources/royale/projects/overrides/interfaces/IB_result.js
index e28bf2e..cfd1886 100644
--- a/compiler-jx/src/test/resources/royale/projects/overrides/interfaces/IB_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/overrides/interfaces/IB_result.js
@@ -56,3 +56,9 @@
     methods: function () {return {};}
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+interfaces.IB.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/overrides/interfaces/IC_result.js b/compiler-jx/src/test/resources/royale/projects/overrides/interfaces/IC_result.js
index 9f0b203..cc176a9 100644
--- a/compiler-jx/src/test/resources/royale/projects/overrides/interfaces/IC_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/overrides/interfaces/IC_result.js
@@ -59,3 +59,9 @@
     methods: function () {return {};}
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+interfaces.IC.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_ambiguous_definition/AmbiguousDefinition_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_ambiguous_definition/AmbiguousDefinition_result.js
index b176467..59ea4a8 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_ambiguous_definition/AmbiguousDefinition_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_ambiguous_definition/AmbiguousDefinition_result.js
@@ -38,7 +38,7 @@
  * @export
  * @type {mypackage.TestClass}
  */
-AmbiguousDefinition.prototype.testClass;
+AmbiguousDefinition.prototype.testClass = null;
 
 
 /**
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/DifferentPackageAsConflict_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/DifferentPackageAsConflict_result.js
index 920736a..e937e30 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/DifferentPackageAsConflict_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/DifferentPackageAsConflict_result.js
@@ -43,7 +43,7 @@
  * @private
  * @type {mypackage.TestClass}
  */
-DifferentPackageAsConflict.prototype.testClass;
+DifferentPackageAsConflict.prototype.testClass = null;
 
 
 /**
@@ -71,3 +71,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+DifferentPackageAsConflict.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/Event_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/Event_result.js
index 7ab655d..e66b810 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/Event_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/Event_result.js
@@ -62,3 +62,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+Event.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/mypackage/TestClass_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/mypackage/TestClass_result.js
index 6b487b5..edc4b35 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/mypackage/TestClass_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/mypackage/TestClass_result.js
@@ -45,7 +45,7 @@
  * @private
  * @type {otherpackage.Event}
  */
-mypackage.TestClass.prototype.event;
+mypackage.TestClass.prototype.event = null;
 
 
 /**
@@ -73,3 +73,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+mypackage.TestClass.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/otherpackage/Event_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/otherpackage/Event_result.js
index 9064c05..17edd42 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/otherpackage/Event_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_different_package_as_conflict/otherpackage/Event_result.js
@@ -62,3 +62,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+otherpackage.Event.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_no_window/Event_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_no_window/Event_result.js
index 7ab655d..2ff7e8d 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_no_window/Event_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_no_window/Event_result.js
@@ -12,7 +12,6 @@
  * limitations under the License.
  */
 /**
- * Generated by Apache Royale Compiler from Event.as
  * Event
  *
  * @fileoverview
@@ -62,3 +61,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+Event.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_no_window/NoConflictNoWindow_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_no_window/NoConflictNoWindow_result.js
index efbdb42..fbac53a 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_no_window/NoConflictNoWindow_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_no_window/NoConflictNoWindow_result.js
@@ -43,7 +43,7 @@
  * @private
  * @type {mypackage.TestClass}
  */
-NoConflictNoWindow.prototype.testClass;
+NoConflictNoWindow.prototype.testClass = null;
 
 
 /**
@@ -71,3 +71,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+NoConflictNoWindow.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_no_window/mypackage/TestClass_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_no_window/mypackage/TestClass_result.js
index c644d1f..73ec794 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_no_window/mypackage/TestClass_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_no_window/mypackage/TestClass_result.js
@@ -43,7 +43,7 @@
  * @private
  * @type {Event}
  */
-mypackage.TestClass.prototype.event;
+mypackage.TestClass.prototype.event = null;
 
 
 /**
@@ -71,3 +71,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+mypackage.TestClass.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_use_window/Event_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_use_window/Event_result.js
index 7ab655d..e66b810 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_use_window/Event_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_use_window/Event_result.js
@@ -62,3 +62,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+Event.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_use_window/NoConflictUseWindow_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_use_window/NoConflictUseWindow_result.js
index 9410ca3..f4e8888 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_use_window/NoConflictUseWindow_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_use_window/NoConflictUseWindow_result.js
@@ -43,7 +43,7 @@
  * @private
  * @type {mypackage.TestClass}
  */
-NoConflictUseWindow.prototype.testClass;
+NoConflictUseWindow.prototype.testClass = null;
 
 
 /**
@@ -71,3 +71,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+NoConflictUseWindow.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_use_window/mypackage/TestClass_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_use_window/mypackage/TestClass_result.js
index c644d1f..73ec794 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_use_window/mypackage/TestClass_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_no_conflict_use_window/mypackage/TestClass_result.js
@@ -43,7 +43,7 @@
  * @private
  * @type {Event}
  */
-mypackage.TestClass.prototype.event;
+mypackage.TestClass.prototype.event = null;
 
 
 /**
@@ -71,3 +71,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+mypackage.TestClass.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/Event_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/Event_result.js
index 7ab655d..e66b810 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/Event_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/Event_result.js
@@ -62,3 +62,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+Event.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/SamePackageAsConflict_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/SamePackageAsConflict_result.js
index ebf818c..cab6477 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/SamePackageAsConflict_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/SamePackageAsConflict_result.js
@@ -43,7 +43,7 @@
  * @private
  * @type {mypackage.TestClass}
  */
-SamePackageAsConflict.prototype.testClass;
+SamePackageAsConflict.prototype.testClass = null;
 
 
 /**
@@ -71,3 +71,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+SamePackageAsConflict.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/mypackage/Event_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/mypackage/Event_result.js
index 6bf3477..03790e1 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/mypackage/Event_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/mypackage/Event_result.js
@@ -62,3 +62,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+mypackage.Event.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/mypackage/TestClass_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/mypackage/TestClass_result.js
index a0a5b4e..1dcdb08 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/mypackage/TestClass_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_same_package_as_conflict/mypackage/TestClass_result.js
@@ -45,7 +45,7 @@
  * @private
  * @type {mypackage.Event}
  */
-mypackage.TestClass.prototype.event;
+mypackage.TestClass.prototype.event = null;
 
 
 /**
@@ -73,3 +73,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+mypackage.TestClass.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/Event_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/Event_result.js
index 7ab655d..e66b810 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/Event_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/Event_result.js
@@ -62,3 +62,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+Event.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/UseWindow_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/UseWindow_result.js
index 2efb878..bf41e5d 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/UseWindow_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/UseWindow_result.js
@@ -43,7 +43,7 @@
  * @private
  * @type {mypackage.TestClass}
  */
-UseWindow.prototype.testClass;
+UseWindow.prototype.testClass = null;
 
 
 /**
@@ -71,3 +71,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+UseWindow.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/mypackage/TestClass_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/mypackage/TestClass_result.js
index 812e1b0..b58f94c 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/mypackage/TestClass_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/mypackage/TestClass_result.js
@@ -46,14 +46,14 @@
  * @private
  * @type {Event}
  */
-mypackage.TestClass.prototype.event1;
+mypackage.TestClass.prototype.event1 = null;
 
 
 /**
  * @private
  * @type {otherpackage.Event}
  */
-mypackage.TestClass.prototype.event2;
+mypackage.TestClass.prototype.event2 = null;
 
 
 /**
@@ -81,3 +81,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+mypackage.TestClass.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/otherpackage/Event_result.js b/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/otherpackage/Event_result.js
index 9064c05..17edd42 100644
--- a/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/otherpackage/Event_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/package_conflicts_use_window/otherpackage/Event_result.js
@@ -62,3 +62,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+otherpackage.Event.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/super/Base_result.js b/compiler-jx/src/test/resources/royale/projects/super/Base_result.js
index 6e626be..1c99d83 100644
--- a/compiler-jx/src/test/resources/royale/projects/super/Base_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/super/Base_result.js
@@ -92,3 +92,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+Base.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/super/Super_result.js b/compiler-jx/src/test/resources/royale/projects/super/Super_result.js
index 4612c43..17ad26f 100644
--- a/compiler-jx/src/test/resources/royale/projects/super/Super_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/super/Super_result.js
@@ -94,3 +94,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+Super.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-jx/src/test/resources/royale/projects/xml_requires/XMLRequire_result.js b/compiler-jx/src/test/resources/royale/projects/xml_requires/XMLRequire_result.js
index 914a071..9b088fd 100644
--- a/compiler-jx/src/test/resources/royale/projects/xml_requires/XMLRequire_result.js
+++ b/compiler-jx/src/test/resources/royale/projects/xml_requires/XMLRequire_result.js
@@ -64,3 +64,9 @@
     }
   };
 };
+/**
+ * @export
+ * @const
+ * @type {number}
+ */
+XMLRequire.prototype.ROYALE_REFLECTION_INFO.compileFlags = 9;
diff --git a/compiler-test-utils/pom.xml b/compiler-test-utils/pom.xml
index 0305699..8384eed 100644
--- a/compiler-test-utils/pom.xml
+++ b/compiler-test-utils/pom.xml
@@ -1,55 +1,65 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.apache.royale.compiler</groupId>
-    <artifactId>royale-compiler-parent</artifactId>
-    <version>0.9.4</version>
-  </parent>
-
-  <artifactId>compiler-test-utils</artifactId>
-  <version>0.9.4</version>
-
-  <name>Apache Royale: Compiler: Test Utils</name>
-  <description>
-    Shared test code, which is needed by the compiler and the compiler-jx test-suites.
-  </description>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-compress</artifactId>
-      <version>1.10</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-      <version>2.4</version>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>4.10</version>
-    </dependency>
-  </dependencies>
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+

+  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.

+

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+  <modelVersion>4.0.0</modelVersion>

+

+  <parent>

+    <groupId>org.apache.royale.compiler</groupId>

+    <artifactId>royale-compiler-parent</artifactId>

+    <version>0.9.6</version>

+  </parent>

+

+  <artifactId>compiler-test-utils</artifactId>

+  <version>0.9.6</version>

+

+  <name>Apache Royale: Compiler: Test Utils</name>

+  <description>

+    Shared test code, which is needed by the compiler and the compiler-jx test-suites.

+  </description>

+

+  <build>

+    <plugins>

+      <plugin>

+        <groupId>io.github.zlika</groupId>

+        <artifactId>reproducible-build-maven-plugin</artifactId>

+        <version>0.9</version>

+      </plugin>

+    </plugins>

+  </build>

+    

+  <dependencies>

+    <dependency>

+      <groupId>org.apache.commons</groupId>

+      <artifactId>commons-compress</artifactId>

+      <version>1.10</version>

+    </dependency>

+    <dependency>

+      <groupId>commons-io</groupId>

+      <artifactId>commons-io</artifactId>

+      <version>2.4</version>

+    </dependency>

+    <dependency>

+      <groupId>junit</groupId>

+      <artifactId>junit</artifactId>

+      <version>4.10</version>

+    </dependency>

+  </dependencies>

+

+</project>

diff --git a/compiler/build.xml b/compiler/build.xml
index 5fb9577..bca3b89 100644
--- a/compiler/build.xml
+++ b/compiler/build.xml
@@ -184,6 +184,8 @@
     <macrodef name="annotate.class">
         <attribute name="file"/>
         <attribute name="annotation"/>
+        <attribute name="datestart"/>
+        <attribute name="dateend"/>
         <sequential>
             <java classname="org.apache.royale.compiler.tools.annotate.AnnotateClass" fork="false">
                 <classpath>
@@ -193,6 +195,8 @@
                 </classpath>
                 <arg value="@{file}"/>
                 <arg value="@{annotation}"/>
+                <arg value="@{datestart}"/>
+                <arg value="@{dateend}"/>
             </java>
         </sequential>
     </macrodef>
@@ -289,9 +293,9 @@
         <antlr2 input="${compiler}/src/main/antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.g"
                 output="${compiler}/target/generated-sources/antlr/org/apache/royale/compiler/internal/parsing/as"/>
         <annotate.class file="${compiler}/target/generated-sources/antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.java"
-                        annotation='@SuppressWarnings("unused")'/>
+                        annotation='@SuppressWarnings("unused")' datestart="" dateend=""/>
         <annotate.class file="${compiler}/target/generated-sources/antlr/org/apache/royale/compiler/internal/parsing/as/ASTokenTypes.java"
-                        annotation='@SuppressWarnings("unused")'/>   
+                        annotation='@SuppressWarnings("unused")' datestart="" dateend=""/>
     </target>
 	
 	<target name="set.metadata.parser.uptodate">
@@ -309,9 +313,9 @@
         <antlr2 input="${compiler}/src/main/antlr/org/apache/royale/compiler/internal/parsing/as/MetadataParser.g"
                 output="${compiler}/target/generated-sources/antlr/org/apache/royale/compiler/internal/parsing/as"/>
         <annotate.class file="${compiler}/target/generated-sources/antlr/org/apache/royale/compiler/internal/parsing/as/MetadataParser.java"
-                         annotation='@SuppressWarnings("all")'/>    
+                         annotation='@SuppressWarnings("all")' datestart="" dateend=""/>
         <annotate.class file="${compiler}/target/generated-sources/antlr/org/apache/royale/compiler/internal/parsing/as/MetadataTokenTypes.java"
-                         annotation='@SuppressWarnings("unused")'/>    
+                         annotation='@SuppressWarnings("unused")' datestart="" dateend=""/>
     </target>
     
     <target name="set.css.lexer.and.parser.uptodate">
@@ -324,10 +328,10 @@
     	<echo message="Generating CSSLexer and CSSParser"/>
         <antlr3 input="${compiler}/src/main/antlr3/org/apache/royale/compiler/internal/css/CSS.g"
                 output="${compiler}/target/generated-sources/antlr3/org/apache/royale/compiler/internal/css"/>
-        <!--<annotate.class file="${compiler}/generated/src/org/apache/royale/compiler/internal/css/CSSLexer.java"
-                        annotation='@SuppressWarnings("unused")'/>-->
-        <!--<annotate.class file="${compiler}/generated/src/org/apache/royale/compiler/internal/css/CSSParser.java"
-                        annotation='@SuppressWarnings("unused")'/>-->
+        <annotate.class file="${compiler}/target/generated-sources/antlr3/org/apache/royale/compiler/internal/css/CSSLexer.java"
+                        annotation='@SuppressWarnings("all")' datestart="// $ANTLR 3.5.2 ***CSS.g" dateend=""/>
+        <annotate.class file="${compiler}/target/generated-sources/antlr3/org/apache/royale/compiler/internal/css/CSSParser.java"
+                        annotation='@SuppressWarnings("all")' datestart="// $ANTLR 3.5.2 ***CSS.g" dateend=""/>
     </target>
         
     <target name="set.css.tree.uptodate">
@@ -340,8 +344,9 @@
     	<echo message="Generating CSSTree"/>
         <antlr3 input="${compiler}/src/main/antlr3/org/apache/royale/compiler/internal/css/CSSTree.g"
                 output="${compiler}/target/generated-sources/antlr3/org/apache/royale/compiler/internal/css"/>
-        <!--<annotate.class file="${compiler}/generated/src/org/apache/royale/compiler/internal/css/CSSTree.java"
-                        annotation='@SuppressWarnings({"rawtypes", "unchecked", "unused"})'/>-->        
+        <annotate.class file="${compiler}/target/generated-sources/antlr3/org/apache/royale/compiler/internal/css/CSSTree.java"
+                        annotation='@SuppressWarnings("all")'
+                        datestart="// $ANTLR 3.5.2 ***CSSTree.g" dateend=""/>
     </target>
         
     <target name="antlr" depends="as.parser, metadata.parser, css.lexer.and.parser, css.tree"
@@ -385,7 +390,7 @@
         <jburg input="${compiler}/src/main/jburg/org/apache/royale/compiler/internal/as/codegen/cmc.jbg"
                output="${compiler}/target/generated-sources/jburg/org/apache/royale/compiler/internal/as/codegen/CmcEmitter.java"/>
         <annotate.class file="${compiler}/target/generated-sources/jburg/org/apache/royale/compiler/internal/as/codegen/CmcEmitter.java"
-                        annotation='@SuppressWarnings({"rawtypes", "unchecked", "unused"})'/>		
+                        annotation='@SuppressWarnings({"rawtypes", "unchecked", "unused", "incomplete-switch"})' datestart="/*  Generated" dateend=" by JBurg"/>
 	</target>
 	
 	<target name="set.css.emitter.uptodate">
@@ -404,7 +409,7 @@
         <jburg input="${compiler}/src/main/jburg/org/apache/royale/compiler/internal/css/codegen/css.jbg"
                output="${compiler}/target/generated-sources/jburg/org/apache/royale/compiler/internal/css/codegen/CSSEmitter.java"/>
         <annotate.class file="${compiler}/target/generated-sources/jburg/org/apache/royale/compiler/internal/css/codegen/CSSEmitter.java"
-                        annotation='@SuppressWarnings({"rawtypes", "unchecked", "unused"})'/>	
+                        annotation='@SuppressWarnings({"rawtypes", "unchecked", "unused", "incomplete-switch"})' datestart="/*  Generated" dateend=" by JBurg"/>
 	</target>
 	
 	<target name="jburg" depends="cmc.emitter, css.emitter"
diff --git a/compiler/pom.xml b/compiler/pom.xml
index 6182cd6..db0c924 100644
--- a/compiler/pom.xml
+++ b/compiler/pom.xml
@@ -1,581 +1,616 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.apache.royale.compiler</groupId>
-    <artifactId>royale-compiler-parent</artifactId>
-    <version>0.9.4</version>
-  </parent>
-
-  <artifactId>compiler</artifactId>
-  <version>0.9.4</version>
-
-  <name>Apache Royale: Compiler: Compiler</name>
-  <description>The Apache Royale Compiler</description>
-
-  <build>
-    <plugins>
-        <plugin>
-          <artifactId>maven-resources-plugin</artifactId>
-          <version>3.1.0</version>
-          <executions>
-            <execution>
-              <id>copy-externc-resources</id>
-              <phase>process-test-resources</phase>
-              <goals>
-                <goal>copy-resources</goal>
-              </goals>
-            <configuration>
-            <outputDirectory>${basedir}/../compiler-externc/target</outputDirectory>
-              <resources>
-                <resource>
-                  <directory>${basedir}/../compiler-externc/src/test/config</directory>
-                </resource>
-              </resources>
-            </configuration>
-          </execution>
-          <execution>
-            <id>copy-custom-resources</id>
-            <phase>process-test-resources</phase>
-            <goals>
-              <goal>copy-resources</goal>
-            </goals>
-            <configuration>
-              <outputDirectory>${basedir}/target</outputDirectory>
-              <resources>
-                <resource>
-                  <directory>${basedir}/src/test/config</directory>
-                </resource>
-              </resources>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <!--
-              Do all the JFlex code generation
-      -->
-      <plugin>
-        <groupId>de.jflex</groupId>
-        <artifactId>maven-jflex-plugin</artifactId>
-        <version>1.4.3</version>
-        <executions>
-          <execution>
-            <id>generate-raw-as-tokenizer</id>
-            <goals>
-              <goal>generate</goal>
-            </goals>
-            <configuration>
-              <outputDirectory>target/generated-sources/jflex</outputDirectory>
-              <lexDefinitions>
-                <lexDefinition>src/main/jflex/org/apache/royale/compiler/internal/parsing/as/RawASTokenizer.lex</lexDefinition>
-              </lexDefinitions>
-              <skeleton>src/main/jflex/org/apache/royale/compiler/internal/parsing/as/skeleton.royale</skeleton>
-            </configuration>
-          </execution>
-          <execution>
-            <id>generate-raw-as-doc-tokenizer</id>
-            <goals>
-              <goal>generate</goal>
-            </goals>
-            <configuration>
-              <outputDirectory>target/generated-sources/jflex</outputDirectory>
-              <lexDefinitions>
-                <lexDefinition>src/main/jflex/org/apache/royale/compiler/internal/parsing/as/RawASDocTokenizer.lex</lexDefinition>
-              </lexDefinitions>
-              <skeleton>src/main/jflex/org/apache/royale/compiler/internal/parsing/as/skeleton.default</skeleton>
-            </configuration>
-          </execution>
-          <execution>
-            <id>generate-raw-mxml-tokenizer</id>
-            <goals>
-              <goal>generate</goal>
-            </goals>
-            <configuration>
-              <outputDirectory>target/generated-sources/jflex</outputDirectory>
-              <lexDefinitions>
-                <lexDefinition>src/main/jflex/org/apache/royale/compiler/internal/parsing/mxml/RawMXMLTokenizer.lex</lexDefinition>
-              </lexDefinitions>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <!--
-            Do all the Antlr2 code generation
-      -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-antlr-plugin</artifactId>
-        <version>2.0-beta-1</version>
-        <executions>
-          <execution>
-            <id>generate-as-parser</id>
-            <goals>
-              <goal>generate</goal>
-            </goals>
-            <configuration>
-              <grammars>org/apache/royale/compiler/internal/parsing/as/ASParser.g</grammars>
-            </configuration>
-          </execution>
-        </executions>
-        <dependencies>
-          <dependency>
-            <groupId>antlr</groupId>
-            <artifactId>antlr</artifactId>
-            <version>2.7.7</version>
-          </dependency>
-        </dependencies>
-      </plugin>
-
-      <!--
-          The generation of the metadata-parser requires Antlr to
-          load ImportMetadataTokenTypes.txt. Unfortunately Altlr
-          looks in the current working directory. The only way to
-          force it to work, is to start a new process with the
-          working directory in the directory containing the file.
-      -->
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>exec-maven-plugin</artifactId>
-        <version>1.5.0</version>
-        <executions>
-          <execution>
-            <id>generate-metadata-parser</id>
-            <phase>generate-sources</phase>
-            <goals>
-              <goal>exec</goal>
-            </goals>
-            <configuration>
-              <executable>java</executable>
-              <arguments>
-                <argument>-classpath</argument>
-                <classpath />
-                <arguments>antlr.Tool</arguments>
-                <argument>-o</argument>
-                <argument>../../../../../../../../../../target/generated-sources/antlr/org/apache/royale/compiler/internal/parsing/as</argument>
-                <argument>MetadataParser.g</argument>
-              </arguments>
-              <workingDirectory>src/main/antlr/org/apache/royale/compiler/internal/parsing/as</workingDirectory>
-              <sourceRoot>target/generated-sources/antlr</sourceRoot>
-            </configuration>
-          </execution>
-          <execution>
-              <id>generate-test-js-typedefs</id>
-              <phase>test-compile</phase>
-              <goals>
-                  <goal>exec</goal>
-              </goals>
-              <configuration>
-                  <executable>java</executable>
-                  <arguments>
-                      <argument>-classpath</argument>
-                      <classpath />
-                      <arguments>org.apache.royale.compiler.clients.EXTERNC</arguments>
-                      <argument>-load-config+=../compiler-externc/src/test/config/externc-config.xml</argument>
-                  </arguments>
-              </configuration>
-          </execution>
-          <execution>
-              <id>generate-test-js-swc</id>
-              <phase>test-compile</phase>
-              <goals>
-                  <goal>exec</goal>
-              </goals>
-              <configuration>
-                  <executable>java</executable>
-                  <arguments>
-                      <argument>-classpath</argument>
-                      <classpath />
-                      <arguments>org.apache.royale.compiler.clients.COMPC</arguments>
-                      <argument>-load-config+=../compiler-externc/target/compile-as-config.xml</argument>
-                      <argument>-output=../compiler-externc/target/js.swc</argument>
-                  </arguments>
-              </configuration>
-          </execution>
-          <execution>
-              <id>generate-test-custom-swc</id>
-              <phase>test-compile</phase>
-              <goals>
-                  <goal>exec</goal>
-              </goals>
-              <configuration>
-                  <executable>java</executable>
-                  <arguments>
-                      <argument>-classpath</argument>
-                      <classpath />
-                      <arguments>org.apache.royale.compiler.clients.COMPC</arguments>
-                      <argument>-load-config+=target/compile-as-config.xml</argument>
-                      <argument>-output=target/custom.swc</argument>
-                  </arguments>
-              </configuration>
-          </execution>
-        </executions>
-      </plugin>
-
-      <!--
-            Do all the JBurg code generation.
-      -->
-      <plugin>
-        <groupId>net.sourceforge.jburg</groupId>
-        <artifactId>jburg-maven-plugin</artifactId>
-        <version>1.10.4</version>
-        <extensions>true</extensions>
-        <executions>
-          <execution>
-            <id>generate-css-emitter</id>
-            <goals>
-              <goal>generate</goal>
-            </goals>
-            <configuration>
-              <includes>
-                <include>CSSEmitter.jbg</include>
-              </includes>
-              <sourceDirectory>src/main/jburg/org/apache/royale/compiler/internal/css/codegen</sourceDirectory>
-              <outputDirectory>target/generated-sources/jburg/org/apache/royale/compiler/internal/css/codegen</outputDirectory>
-            </configuration>
-          </execution>
-          <execution>
-            <id>generate-cmc-emitter</id>
-            <goals>
-              <goal>generate</goal>
-            </goals>
-            <configuration>
-              <includes>
-                <include>CmcEmitter.jbg</include>
-              </includes>
-              <sourceDirectory>src/main/jburg/org/apache/royale/compiler/internal/as/codegen</sourceDirectory>
-              <outputDirectory>target/generated-sources/jburg/org/apache/royale/compiler/internal/as/codegen</outputDirectory>
-            </configuration>
-          </execution>
-        </executions>
-        <configuration>
-          <!-- debug=true generates the "dump" method for Emitters, which is used for debugging -->
-          <debug>true</debug>
-        </configuration>
-        <dependencies>
-          <dependency>
-            <groupId>net.sourceforge.jburg</groupId>
-            <artifactId>jburg</artifactId>
-            <version>1.10.3</version>
-          </dependency>
-          <dependency>
-            <groupId>org.apache.royale.compiler</groupId>
-            <artifactId>compiler-jburg-types</artifactId>
-            <version>${compiler-jburg-types.version}</version>
-          </dependency>
-        </dependencies>
-      </plugin>
-
-      <!--
-            Do all the Antlr3 code generation.
-      -->
-      <plugin>
-        <groupId>org.antlr</groupId>
-        <artifactId>antlr3-maven-plugin</artifactId>
-        <version>3.5.2</version>
-        <executions>
-          <execution>
-            <id>generate-csslexer-and-cssparser</id>
-            <goals>
-              <goal>antlr</goal>
-            </goals>
-            <configuration>
-              <includes>
-                <include>CSS.g</include>
-              </includes>
-              <sourceDirectory>src/main/antlr3/org/apache/royale/compiler/internal/css</sourceDirectory>
-              <outputDirectory>target/generated-sources/antlr3/org/apache/royale/compiler/internal/css</outputDirectory>
-            </configuration>
-          </execution>
-          <execution>
-            <id>generate-csstree</id>
-            <goals>
-              <goal>antlr</goal>
-            </goals>
-            <configuration>
-              <includes>
-                <include>CSSTree.g</include>
-              </includes>
-              <sourceDirectory>src/main/antlr3/org/apache/royale/compiler/internal/css</sourceDirectory>
-              <outputDirectory>target/generated-sources/antlr3/org/apache/royale/compiler/internal/css</outputDirectory>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-
-      <!--
-              Do all the custom processing with the royale build tools.
-      -->
-      <plugin>
-        <groupId>org.apache.royale.compiler</groupId>
-        <artifactId>compiler-build-tools</artifactId>
-        <version>${compiler-build-tools.version}</version>
-        <executions>
-          <execution>
-            <id>generate-unknown-tree-handler</id>
-            <goals>
-              <goal>generate-unknown-tree-handler</goal>
-            </goals>
-            <configuration>
-              <inputFile>org/apache/royale/compiler/internal/as/codegen/UnknownTreeHandlerPatterns.xml</inputFile>
-              <outputFile>org/apache/royale/compiler/internal/as/codegen/UnknownTreeHandlerPatterns.java</outputFile>
-            </configuration>
-          </execution>
-          <execution>
-            <id>add-suppress-unused-warnings-annotations</id>
-            <goals>
-              <goal>add-class-annotation</goal>
-            </goals>
-            <configuration>
-              <includes>
-                <include>antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.java</include>
-                <include>antlr/org/apache/royale/compiler/internal/parsing/as/ASTokenTypes.java</include>
-                <include>antlr/org/apache/royale/compiler/internal/parsing/as/MetadataTokenTypes.java</include>
-              </includes>
-              <annotation>@SuppressWarnings("unused")</annotation>
-            </configuration>
-          </execution>
-          <execution>
-            <id>add-suppress-all-warnings-annotations-jburg</id>
-            <goals>
-              <goal>add-class-annotation</goal>
-            </goals>
-            <configuration>
-              <includes>
-                <include>antlr/org/apache/royale/compiler/internal/parsing/as/MetadataParser.java</include>
-              </includes>
-              <annotation>@SuppressWarnings("all")</annotation>
-            </configuration>
-          </execution>
-          <execution>
-            <id>add-suppress-rawtypes-unchecked-unused-warnings-annotations</id>
-            <goals>
-              <goal>add-class-annotation</goal>
-            </goals>
-            <configuration>
-              <includes>
-                <include>jburg/org/apache/royale/compiler/internal/css/codegen/CSSEmitter.java</include>
-                <include>jburg/org/apache/royale/compiler/internal/as/codegen/CmcEmitter.java</include>
-              </includes>
-              <annotation>@SuppressWarnings({"rawtypes", "unchecked", "unused"})</annotation>
-            </configuration>
-          </execution>
-          <execution>
-            <id>generate-problems-enum</id>
-            <goals>
-              <goal>generate-problems-enum</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>generate-problems-resource-bundle</id>
-            <goals>
-              <goal>generate-problems-resource-bundle</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-
-      <!-- Make the surefire execute all unit-tests -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <version>2.19</version>
-        <configuration>
-          <includes>
-            <include>**/*Tests.java</include>
-          </includes>
-          <excludes>
-            <exclude>as/**/*Tests.java</exclude>
-            <exclude>f/**</exclude>
-            <exclude>mxml/tags/**</exclude>
-            <exclude>properties/**</exclude>
-            <exclude>**/MXMLComponentTagTests.java</exclude>
-            <exclude>**/MXMLComponentNodeTests.java</exclude>
-            <exclude>**/MXMLHTTPServiceTagTests.java</exclude>
-            <exclude>**/MXMLModelTagTests.java</exclude>
-            <exclude>**/MXMLRemoteObjectNodeTests.java</exclude>
-            <exclude>**/MXMLWebServiceNodeTests.java</exclude>
-            <exclude>**/MXMLDesignLayerNodeTests.java</exclude>
-            <exclude>**/MXMLHTTPServiceNodeTests.java</exclude>
-            <exclude>**/MXMLModelNodeTests.java</exclude>
-            <exclude>**/MXMLRemoteObjectTagTests.java</exclude>
-            <exclude>**/MXMLStateNodeTests.java</exclude>
-            <exclude>**/MXMLVectorNodeTests.java</exclude>
-            <exclude>**/MXMLWebServiceTagTests.java</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-failsafe-plugin</artifactId>
-        <version>2.18.1</version>
-        <configuration>
-          <includes>
-            <include>as/**/*Tests.java</include>
-          </includes>
-          <excludes>
-            <exclude>f/**</exclude>
-            <exclude>mxml/tags/**</exclude>
-            <exclude>properties/**</exclude>
-            <exclude>**/MXMLComponentTagTests.java</exclude>
-            <exclude>**/MXMLComponentNodeTests.java</exclude>
-            <exclude>**/MXMLHTTPServiceTagTests.java</exclude>
-            <exclude>**/MXMLModelTagTests.java</exclude>
-            <exclude>**/MXMLRemoteObjectNodeTests.java</exclude>
-            <exclude>**/MXMLWebServiceNodeTests.java</exclude>
-            <exclude>**/MXMLDesignLayerNodeTests.java</exclude>
-            <exclude>**/MXMLHTTPServiceNodeTests.java</exclude>
-            <exclude>**/MXMLModelNodeTests.java</exclude>
-            <exclude>**/MXMLRemoteObjectTagTests.java</exclude>
-            <exclude>**/MXMLStateNodeTests.java</exclude>
-            <exclude>**/MXMLVectorNodeTests.java</exclude>
-            <exclude>**/MXMLWebServiceTagTests.java</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
-  <profiles>
-    <!--
-        This profile adds one test, that relies on the original FDK being
-        available as it compiles each project in the framework/projects
-        directory. It requires some environment variables being set.
-    -->
-    <profile>
-      <id>include-sdk-compile-tests</id>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-failsafe-plugin</artifactId>
-            <configuration>
-              <includes combine.children="append">
-                <include>f/**/*Tests.java</include>
-                <include>mxml/**/*Tests.java</include>
-                <include>properties/**/*Tests.java</include>
-                <include>**/MXMLComponentTagTests.java</include>
-                <include>**/MXMLComponentNodeTests.java</include>
-                <include>**/MXMLHTTPServiceTagTests.java</include>
-                <include>**/MXMLModelTagTests.java</include>
-                <include>**/MXMLRemoteObjectNodeTests.java</include>
-                <include>**/MXMLWebServiceNodeTests.java</include>
-                <include>**/MXMLDesignLayerNodeTests.java</include>
-                <include>**/MXMLHTTPServiceNodeTests.java</include>
-                <include>**/MXMLModelNodeTests.java</include>
-                <include>**/MXMLRemoteObjectTagTests.java</include>
-                <include>**/MXMLStateNodeTests.java</include>
-                <include>**/MXMLVectorNodeTests.java</include>
-                <include>**/MXMLWebServiceTagTests.java</include>
-              </includes>
-            </configuration>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>compiler-jburg-types</artifactId>
-      <version>${compiler-jburg-types.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>compiler-common</artifactId>
-      <version>0.9.4</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.flex</groupId>
-      <artifactId>flex-tool-api</artifactId>
-      <version>1.0.0</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-      <version>2.4</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-cli</groupId>
-      <artifactId>commons-cli</artifactId>
-      <version>1.2</version>
-    </dependency>
-    <dependency>
-      <groupId>org.antlr</groupId>
-      <artifactId>antlr</artifactId>
-      <version>3.3</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-      <version>20.0</version>
-    </dependency>
-    <dependency>
-      <groupId>net.sourceforge.jburg</groupId>
-      <artifactId>jburg</artifactId>
-      <version>1.10.3</version>
-    </dependency>
-    <dependency>
-      <groupId>de.jflex</groupId>
-      <artifactId>jflex</artifactId>
-      <version>1.6.0</version>
-      <exclusions>
-        <exclusion>
-          <groupId>org.apache.ant</groupId>
-          <artifactId>ant</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.b1.pack</groupId>
-      <artifactId>lzma-sdk-4j</artifactId>
-      <version>9.22.0</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>compiler-test-utils</artifactId>
-      <version>0.9.4</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>compiler-externc</artifactId>
-      <version>0.9.4</version>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>4.10</version>
-      <scope>test</scope>
-    </dependency>
-    <!-- TODO: Currently only needed for the duplicate FlashplayerSecurityHandler -->
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-lang3</artifactId>
-      <version>3.4</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+

+  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.

+

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+  <modelVersion>4.0.0</modelVersion>

+

+  <parent>

+    <groupId>org.apache.royale.compiler</groupId>

+    <artifactId>royale-compiler-parent</artifactId>

+    <version>0.9.6</version>

+  </parent>

+

+  <artifactId>compiler</artifactId>

+  <version>0.9.6</version>

+

+  <name>Apache Royale: Compiler: Compiler</name>

+  <description>The Apache Royale Compiler</description>

+

+  <build>

+    <plugins>

+        <plugin>

+            <groupId>io.github.zlika</groupId>

+            <artifactId>reproducible-build-maven-plugin</artifactId>

+            <version>0.9</version>

+        </plugin>

+        <plugin>

+          <artifactId>maven-resources-plugin</artifactId>

+          <version>3.1.0</version>

+          <executions>

+            <execution>

+              <id>copy-externc-resources</id>

+              <phase>process-test-resources</phase>

+              <goals>

+                <goal>copy-resources</goal>

+              </goals>

+            <configuration>

+            <outputDirectory>${basedir}/../compiler-externc/target</outputDirectory>

+              <resources>

+                <resource>

+                  <directory>${basedir}/../compiler-externc/src/test/config</directory>

+                </resource>

+              </resources>

+            </configuration>

+          </execution>

+          <execution>

+            <id>copy-custom-resources</id>

+            <phase>process-test-resources</phase>

+            <goals>

+              <goal>copy-resources</goal>

+            </goals>

+            <configuration>

+              <outputDirectory>${basedir}/target</outputDirectory>

+              <resources>

+                <resource>

+                  <directory>${basedir}/src/test/config</directory>

+                </resource>

+              </resources>

+            </configuration>

+          </execution>

+        </executions>

+      </plugin>

+      <!--

+              Do all the JFlex code generation

+      -->

+      <plugin>

+        <groupId>de.jflex</groupId>

+        <artifactId>maven-jflex-plugin</artifactId>

+        <version>1.4.3</version>

+        <executions>

+          <execution>

+            <id>generate-raw-as-tokenizer</id>

+            <goals>

+              <goal>generate</goal>

+            </goals>

+            <configuration>

+              <outputDirectory>target/generated-sources/jflex</outputDirectory>

+              <lexDefinitions>

+                <lexDefinition>src/main/jflex/org/apache/royale/compiler/internal/parsing/as/RawASTokenizer.lex</lexDefinition>

+              </lexDefinitions>

+              <skeleton>src/main/jflex/org/apache/royale/compiler/internal/parsing/as/skeleton.royale</skeleton>

+            </configuration>

+          </execution>

+          <execution>

+            <id>generate-raw-as-doc-tokenizer</id>

+            <goals>

+              <goal>generate</goal>

+            </goals>

+            <configuration>

+              <outputDirectory>target/generated-sources/jflex</outputDirectory>

+              <lexDefinitions>

+                <lexDefinition>src/main/jflex/org/apache/royale/compiler/internal/parsing/as/RawASDocTokenizer.lex</lexDefinition>

+              </lexDefinitions>

+              <skeleton>src/main/jflex/org/apache/royale/compiler/internal/parsing/as/skeleton.default</skeleton>

+            </configuration>

+          </execution>

+          <execution>

+            <id>generate-raw-mxml-tokenizer</id>

+            <goals>

+              <goal>generate</goal>

+            </goals>

+            <configuration>

+              <outputDirectory>target/generated-sources/jflex</outputDirectory>

+              <lexDefinitions>

+                <lexDefinition>src/main/jflex/org/apache/royale/compiler/internal/parsing/mxml/RawMXMLTokenizer.lex</lexDefinition>

+              </lexDefinitions>

+            </configuration>

+          </execution>

+        </executions>

+      </plugin>

+      <!--

+            Do all the Antlr2 code generation

+      -->

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-antlr-plugin</artifactId>

+        <version>2.0-beta-1</version>

+        <executions>

+          <execution>

+            <id>generate-as-parser</id>

+            <goals>

+              <goal>generate</goal>

+            </goals>

+            <configuration>

+              <grammars>org/apache/royale/compiler/internal/parsing/as/ASParser.g</grammars>

+            </configuration>

+          </execution>

+        </executions>

+        <dependencies>

+          <dependency>

+            <groupId>antlr</groupId>

+            <artifactId>antlr</artifactId>

+            <version>2.7.7</version>

+          </dependency>

+        </dependencies>

+      </plugin>

+

+      <!--

+          The generation of the metadata-parser requires Antlr to

+          load ImportMetadataTokenTypes.txt. Unfortunately Altlr

+          looks in the current working directory. The only way to

+          force it to work, is to start a new process with the

+          working directory in the directory containing the file.

+      -->

+      <plugin>

+        <groupId>org.codehaus.mojo</groupId>

+        <artifactId>exec-maven-plugin</artifactId>

+        <version>1.5.0</version>

+        <executions>

+          <execution>

+            <id>generate-metadata-parser</id>

+            <phase>generate-sources</phase>

+            <goals>

+              <goal>exec</goal>

+            </goals>

+            <configuration>

+              <executable>java</executable>

+              <arguments>

+                <argument>-classpath</argument>

+                <classpath />

+                <arguments>antlr.Tool</arguments>

+                <argument>-o</argument>

+                <argument>../../../../../../../../../../target/generated-sources/antlr/org/apache/royale/compiler/internal/parsing/as</argument>

+                <argument>MetadataParser.g</argument>

+              </arguments>

+              <workingDirectory>src/main/antlr/org/apache/royale/compiler/internal/parsing/as</workingDirectory>

+              <sourceRoot>target/generated-sources/antlr</sourceRoot>

+            </configuration>

+          </execution>

+          <execution>

+              <id>generate-test-js-typedefs</id>

+              <phase>test-compile</phase>

+              <goals>

+                  <goal>exec</goal>

+              </goals>

+              <configuration>

+                  <executable>java</executable>

+                  <arguments>

+                      <argument>-classpath</argument>

+                      <classpath />

+                      <arguments>org.apache.royale.compiler.clients.EXTERNC</arguments>

+                      <argument>-load-config+=../compiler-externc/src/test/config/externc-config.xml</argument>

+                  </arguments>

+              </configuration>

+          </execution>

+          <execution>

+              <id>generate-test-js-swc</id>

+              <phase>test-compile</phase>

+              <goals>

+                  <goal>exec</goal>

+              </goals>

+              <configuration>

+                  <executable>java</executable>

+                  <arguments>

+                      <argument>-classpath</argument>

+                      <classpath />

+                      <arguments>org.apache.royale.compiler.clients.COMPC</arguments>

+                      <argument>-load-config+=../compiler-externc/target/compile-as-config.xml</argument>

+                      <argument>-output=../compiler-externc/target/js.swc</argument>

+                  </arguments>

+              </configuration>

+          </execution>

+          <execution>

+              <id>generate-test-custom-swc</id>

+              <phase>test-compile</phase>

+              <goals>

+                  <goal>exec</goal>

+              </goals>

+              <configuration>

+                  <executable>java</executable>

+                  <arguments>

+                      <argument>-classpath</argument>

+                      <classpath />

+                      <arguments>org.apache.royale.compiler.clients.COMPC</arguments>

+                      <argument>-load-config+=target/compile-as-config.xml</argument>

+                      <argument>-output=target/custom.swc</argument>

+                  </arguments>

+              </configuration>

+          </execution>

+        </executions>

+      </plugin>

+

+      <!--

+            Do all the JBurg code generation.

+      -->

+      <plugin>

+        <groupId>net.sourceforge.jburg</groupId>

+        <artifactId>jburg-maven-plugin</artifactId>

+        <version>1.10.4</version>

+        <extensions>true</extensions>

+        <executions>

+          <execution>

+            <id>generate-css-emitter</id>

+            <goals>

+              <goal>generate</goal>

+            </goals>

+            <configuration>

+              <includes>

+                <include>CSSEmitter.jbg</include>

+              </includes>

+              <sourceDirectory>src/main/jburg/org/apache/royale/compiler/internal/css/codegen</sourceDirectory>

+              <outputDirectory>target/generated-sources/jburg/org/apache/royale/compiler/internal/css/codegen</outputDirectory>

+            </configuration>

+          </execution>

+          <execution>

+            <id>generate-cmc-emitter</id>

+            <goals>

+              <goal>generate</goal>

+            </goals>

+            <configuration>

+              <includes>

+                <include>CmcEmitter.jbg</include>

+              </includes>

+              <sourceDirectory>src/main/jburg/org/apache/royale/compiler/internal/as/codegen</sourceDirectory>

+              <outputDirectory>target/generated-sources/jburg/org/apache/royale/compiler/internal/as/codegen</outputDirectory>

+            </configuration>

+          </execution>

+        </executions>

+        <configuration>

+          <!-- debug=true generates the "dump" method for Emitters, which is used for debugging -->

+          <debug>true</debug>

+        </configuration>

+        <dependencies>

+          <!-- this needs to be first in order to patch jburg -->

+          <dependency>

+            <groupId>org.apache.royale.compiler</groupId>

+            <artifactId>compiler-jburg-types</artifactId>

+            <version>${compiler-jburg-types.version}</version>

+          </dependency>

+          <dependency>

+            <groupId>net.sourceforge.jburg</groupId>

+            <artifactId>jburg</artifactId>

+            <version>1.10.3</version>

+          </dependency>

+        </dependencies>

+      </plugin>

+

+      <!--

+            Do all the Antlr3 code generation.

+      -->

+      <plugin>

+        <groupId>org.antlr</groupId>

+        <artifactId>antlr3-maven-plugin</artifactId>

+        <version>3.5.2</version>

+        <executions>

+          <execution>

+            <id>generate-csslexer-and-cssparser</id>

+            <goals>

+              <goal>antlr</goal>

+            </goals>

+            <configuration>

+              <includes>

+                <include>CSS.g</include>

+              </includes>

+              <sourceDirectory>src/main/antlr3/org/apache/royale/compiler/internal/css</sourceDirectory>

+              <outputDirectory>target/generated-sources/antlr3/org/apache/royale/compiler/internal/css</outputDirectory>

+            </configuration>

+          </execution>

+          <execution>

+            <id>generate-csstree</id>

+            <goals>

+              <goal>antlr</goal>

+            </goals>

+            <configuration>

+              <includes>

+                <include>CSSTree.g</include>

+              </includes>

+              <sourceDirectory>src/main/antlr3/org/apache/royale/compiler/internal/css</sourceDirectory>

+              <outputDirectory>target/generated-sources/antlr3/org/apache/royale/compiler/internal/css</outputDirectory>

+            </configuration>

+          </execution>

+        </executions>

+      </plugin>

+

+      <!--

+              Do all the custom processing with the royale build tools.

+      -->

+      <plugin>

+        <groupId>org.apache.royale.compiler</groupId>

+        <artifactId>compiler-build-tools</artifactId>

+        <version>${compiler-build-tools.version}</version>

+        <executions>

+          <execution>

+            <id>generate-unknown-tree-handler</id>

+            <goals>

+              <goal>generate-unknown-tree-handler</goal>

+            </goals>

+            <configuration>

+              <inputFile>org/apache/royale/compiler/internal/as/codegen/UnknownTreeHandlerPatterns.xml</inputFile>

+              <outputFile>org/apache/royale/compiler/internal/as/codegen/UnknownTreeHandlerPatterns.java</outputFile>

+            </configuration>

+          </execution>

+          <execution>

+            <id>add-suppress-unused-warnings-annotations</id>

+            <goals>

+              <goal>add-class-annotation</goal>

+            </goals>

+            <configuration>

+              <includes>

+                <include>antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.java</include>

+                <include>antlr/org/apache/royale/compiler/internal/parsing/as/ASTokenTypes.java</include>

+                <include>antlr/org/apache/royale/compiler/internal/parsing/as/MetadataTokenTypes.java</include>

+              </includes>

+              <annotation>@SuppressWarnings("unused")</annotation>

+            </configuration>

+          </execution>

+          <execution>

+            <id>add-suppress-all-warnings-annotations-css</id>

+            <goals>

+              <goal>add-class-annotation</goal>

+            </goals>

+            <configuration>

+              <includes>

+                <include>antlr3/org/apache/royale/compiler/internal/css/CSSLexer.java</include>

+                <include>antlr3/org/apache/royale/compiler/internal/css/CSSParser.java</include>

+              </includes>

+              <annotation>@SuppressWarnings("all")</annotation>

+              <dateStart>// $ANTLR 3.5.2 ***CSS.g</dateStart>

+            </configuration>

+          </execution>

+          <execution>

+            <id>add-suppress-all-warnings-annotations-csstree</id>

+            <goals>

+              <goal>add-class-annotation</goal>

+            </goals>

+            <configuration>

+              <includes>

+                <include>antlr3/org/apache/royale/compiler/internal/css/CSSTree.java</include>

+              </includes>

+              <annotation>@SuppressWarnings("all")</annotation>

+              <dateStart>// $ANTLR 3.5.2 ***CSSTree.g</dateStart>

+            </configuration>

+          </execution>

+          <execution>

+            <id>add-suppress-all-warnings-annotations-jburg</id>

+            <goals>

+              <goal>add-class-annotation</goal>

+            </goals>

+            <configuration>

+              <includes>

+                <include>antlr/org/apache/royale/compiler/internal/parsing/as/MetadataParser.java</include>

+              </includes>

+              <annotation>@SuppressWarnings("all")</annotation>

+            </configuration>

+          </execution>

+          <execution>

+            <id>add-suppress-rawtypes-unchecked-unused-warnings-annotations</id>

+            <goals>

+              <goal>add-class-annotation</goal>

+            </goals>

+            <configuration>

+              <includes>

+                <include>jburg/org/apache/royale/compiler/internal/css/codegen/CSSEmitter.java</include>

+                <include>jburg/org/apache/royale/compiler/internal/as/codegen/CmcEmitter.java</include>

+              </includes>

+              <annotation>@SuppressWarnings({"rawtypes", "unchecked", "unused"})</annotation>

+              <dateStart>/*  Generated</dateStart>

+              <dateEnd> by JBurg</dateEnd>

+            </configuration>

+          </execution>

+          <execution>

+            <id>generate-problems-enum</id>

+            <goals>

+              <goal>generate-problems-enum</goal>

+            </goals>

+          </execution>

+          <execution>

+            <id>generate-problems-resource-bundle</id>

+            <goals>

+              <goal>generate-problems-resource-bundle</goal>

+            </goals>

+          </execution>

+        </executions>

+      </plugin>

+

+      <!-- Make the surefire execute all unit-tests -->

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-surefire-plugin</artifactId>

+        <version>2.19</version>

+        <configuration>

+          <includes>

+            <include>**/*Tests.java</include>

+          </includes>

+          <excludes>

+            <exclude>as/**/*Tests.java</exclude>

+            <exclude>f/**</exclude>

+            <exclude>mxml/tags/**</exclude>

+            <exclude>properties/**</exclude>

+            <exclude>**/MXMLComponentTagTests.java</exclude>

+            <exclude>**/MXMLComponentNodeTests.java</exclude>

+            <exclude>**/MXMLHTTPServiceTagTests.java</exclude>

+            <exclude>**/MXMLModelTagTests.java</exclude>

+            <exclude>**/MXMLRemoteObjectNodeTests.java</exclude>

+            <exclude>**/MXMLWebServiceNodeTests.java</exclude>

+            <exclude>**/MXMLDesignLayerNodeTests.java</exclude>

+            <exclude>**/MXMLHTTPServiceNodeTests.java</exclude>

+            <exclude>**/MXMLModelNodeTests.java</exclude>

+            <exclude>**/MXMLRemoteObjectTagTests.java</exclude>

+            <exclude>**/MXMLStateNodeTests.java</exclude>

+            <exclude>**/MXMLVectorNodeTests.java</exclude>

+            <exclude>**/MXMLWebServiceTagTests.java</exclude>

+          </excludes>

+        </configuration>

+      </plugin>

+

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-failsafe-plugin</artifactId>

+        <version>2.18.1</version>

+        <configuration>

+          <includes>

+            <include>as/**/*Tests.java</include>

+          </includes>

+          <excludes>

+            <exclude>f/**</exclude>

+            <exclude>mxml/tags/**</exclude>

+            <exclude>properties/**</exclude>

+            <exclude>**/MXMLComponentTagTests.java</exclude>

+            <exclude>**/MXMLComponentNodeTests.java</exclude>

+            <exclude>**/MXMLHTTPServiceTagTests.java</exclude>

+            <exclude>**/MXMLModelTagTests.java</exclude>

+            <exclude>**/MXMLRemoteObjectNodeTests.java</exclude>

+            <exclude>**/MXMLWebServiceNodeTests.java</exclude>

+            <exclude>**/MXMLDesignLayerNodeTests.java</exclude>

+            <exclude>**/MXMLHTTPServiceNodeTests.java</exclude>

+            <exclude>**/MXMLModelNodeTests.java</exclude>

+            <exclude>**/MXMLRemoteObjectTagTests.java</exclude>

+            <exclude>**/MXMLStateNodeTests.java</exclude>

+            <exclude>**/MXMLVectorNodeTests.java</exclude>

+            <exclude>**/MXMLWebServiceTagTests.java</exclude>

+          </excludes>

+        </configuration>

+      </plugin>

+    </plugins>

+  </build>

+

+  <profiles>

+    <!--

+        This profile adds one test, that relies on the original FDK being

+        available as it compiles each project in the framework/projects

+        directory. It requires some environment variables being set.

+    -->

+    <profile>

+      <id>include-sdk-compile-tests</id>

+      <build>

+        <plugins>

+          <plugin>

+            <groupId>org.apache.maven.plugins</groupId>

+            <artifactId>maven-failsafe-plugin</artifactId>

+            <configuration>

+              <includes combine.children="append">

+                <include>f/**/*Tests.java</include>

+                <include>mxml/**/*Tests.java</include>

+                <include>properties/**/*Tests.java</include>

+                <include>**/MXMLComponentTagTests.java</include>

+                <include>**/MXMLComponentNodeTests.java</include>

+                <include>**/MXMLHTTPServiceTagTests.java</include>

+                <include>**/MXMLModelTagTests.java</include>

+                <include>**/MXMLRemoteObjectNodeTests.java</include>

+                <include>**/MXMLWebServiceNodeTests.java</include>

+                <include>**/MXMLDesignLayerNodeTests.java</include>

+                <include>**/MXMLHTTPServiceNodeTests.java</include>

+                <include>**/MXMLModelNodeTests.java</include>

+                <include>**/MXMLRemoteObjectTagTests.java</include>

+                <include>**/MXMLStateNodeTests.java</include>

+                <include>**/MXMLVectorNodeTests.java</include>

+                <include>**/MXMLWebServiceTagTests.java</include>

+              </includes>

+            </configuration>

+          </plugin>

+        </plugins>

+      </build>

+    </profile>

+  </profiles>

+

+  <dependencies>

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>compiler-jburg-types</artifactId>

+      <version>${compiler-jburg-types.version}</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>compiler-common</artifactId>

+      <version>0.9.6</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.flex</groupId>

+      <artifactId>flex-tool-api</artifactId>

+      <version>1.0.0</version>

+    </dependency>

+    <dependency>

+      <groupId>commons-io</groupId>

+      <artifactId>commons-io</artifactId>

+      <version>2.4</version>

+    </dependency>

+    <dependency>

+      <groupId>commons-cli</groupId>

+      <artifactId>commons-cli</artifactId>

+      <version>1.2</version>

+    </dependency>

+    <dependency>

+      <groupId>org.antlr</groupId>

+      <artifactId>antlr</artifactId>

+      <version>3.3</version>

+    </dependency>

+    <dependency>

+      <groupId>com.google.guava</groupId>

+      <artifactId>guava</artifactId>

+      <version>25.1-jre</version>

+    </dependency>

+    <dependency>

+      <groupId>net.sourceforge.jburg</groupId>

+      <artifactId>jburg</artifactId>

+      <version>1.10.3</version>

+    </dependency>

+    <dependency>

+      <groupId>de.jflex</groupId>

+      <artifactId>jflex</artifactId>

+      <version>1.6.0</version>

+      <exclusions>

+        <exclusion>

+          <groupId>org.apache.ant</groupId>

+          <artifactId>ant</artifactId>

+        </exclusion>

+      </exclusions>

+    </dependency>

+    <dependency>

+      <groupId>org.b1.pack</groupId>

+      <artifactId>lzma-sdk-4j</artifactId>

+      <version>9.22.0</version>

+    </dependency>

+

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>compiler-test-utils</artifactId>

+      <version>0.9.6</version>

+      <scope>test</scope>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>compiler-externc</artifactId>

+      <version>0.9.6</version>

+    </dependency>

+    <dependency>

+      <groupId>junit</groupId>

+      <artifactId>junit</artifactId>

+      <version>4.10</version>

+      <scope>test</scope>

+    </dependency>

+    <!-- TODO: Currently only needed for the duplicate FlashplayerSecurityHandler -->

+    <dependency>

+      <groupId>org.apache.commons</groupId>

+      <artifactId>commons-lang3</artifactId>

+      <version>3.4</version>

+      <scope>test</scope>

+    </dependency>

+  </dependencies>

+

+</project>

diff --git a/compiler/src/main/antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.g b/compiler/src/main/antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.g
index c9b1528..8a6a299 100644
--- a/compiler/src/main/antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.g
+++ b/compiler/src/main/antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.g
@@ -212,7 +212,7 @@
 
 /**
  * Matches an attribute such as:
- * - Modifiers: dynamic, final, native, override, static, virtual.
+ * - Modifiers: dynamic, final, native, override, static, virtual, abstract.
  * - Namespace names.
  * - Reserved namespace names: internal, private, public, protected.
  *
@@ -580,6 +580,7 @@
         |   TOKEN_MODIFIER_STATIC
         |   TOKEN_MODIFIER_NATIVE
         |   TOKEN_MODIFIER_VIRTUAL
+        |   TOKEN_MODIFIER_ABSTRACT
         )
         { modifierNode = new ModifierNode((ASToken) modifierT);	}
 	;
@@ -1884,6 +1885,7 @@
  			b = t.getContentsNode();
  		}
  		caseStatementList[b]
+        |   asDocComment
  	;
  	exception catch [RecognitionException ex] {handleParsingError(ex);  }
 
diff --git a/compiler/src/main/java/org/apache/royale/abc/semantics/Block.java b/compiler/src/main/java/org/apache/royale/abc/semantics/Block.java
index 930cf90..1d89d30 100644
--- a/compiler/src/main/java/org/apache/royale/abc/semantics/Block.java
+++ b/compiler/src/main/java/org/apache/royale/abc/semantics/Block.java
@@ -48,7 +48,7 @@
     /**
      * Successors to this block.
      */
-    private Set<IBasicBlock> successors = Collections.emptySet();
+    private Collection<IBasicBlock> successors = Collections.emptySet();
 
     /**
      * @return successors of this block.
@@ -59,6 +59,12 @@
     }
 
     /**
+     * block number assigned by ControlFlowGraph.  So far,
+     * only used to try to guarantee order in lists/collections
+     */
+    public int blocknum;
+    
+    /**
      * Add a successor to this block.
      * 
      * @param succ - the successor block.
@@ -66,7 +72,7 @@
     void addSuccessor(IBasicBlock succ)
     {
         if (this.successors.size() == 0)
-            this.successors = new HashSet<IBasicBlock>();
+            this.successors = new ArrayList<IBasicBlock>();
 
         this.successors.add(succ);
     }
diff --git a/compiler/src/main/java/org/apache/royale/abc/semantics/ControlFlowGraph.java b/compiler/src/main/java/org/apache/royale/abc/semantics/ControlFlowGraph.java
index de0c42b..4f2800d 100644
--- a/compiler/src/main/java/org/apache/royale/abc/semantics/ControlFlowGraph.java
+++ b/compiler/src/main/java/org/apache/royale/abc/semantics/ControlFlowGraph.java
@@ -23,10 +23,13 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
 
 import org.apache.royale.abc.ABCConstants;
 import org.apache.royale.abc.graph.IBasicBlock;
@@ -34,6 +37,8 @@
 import org.apache.royale.abc.graph.algorithms.DepthFirstPreorderIterator;
 import org.apache.royale.abc.graph.algorithms.DominatorTree;
 import org.apache.royale.abc.visitors.IFlowGraphVisitor;
+import org.apache.royale.compiler.css.ICSSDocument;
+import org.apache.royale.compiler.internal.projects.LibraryPathManager;
 
 /**
  * A ControlFlowGraph represents the flow of control through a sequence of
@@ -190,7 +195,24 @@
 
         // We've seen all the instructions now, so we can compute the blocks that
         // each label corresponds to, and fill in the rest of the graph
-        for (Map.Entry<Block, Collection<Label>> entry : successor_labels.entrySet())
+        Set<Entry<Block, Collection<Label>>> entries = successor_labels.entrySet();
+        ArrayList<Entry<Block, Collection<Label>>> listOfEntries = new ArrayList<Entry<Block, Collection<Label>>>();
+        for (Map.Entry<Block, Collection<Label>> entry : entries)
+        	listOfEntries.add(entry);
+        Collections.sort(listOfEntries, new Comparator<Entry<Block, Collection<Label>>>()
+        {
+            /**
+             * Sort by blocknum.
+             */
+            @Override
+            public int compare(Entry<Block, Collection<Label>> o1, Entry<Block, Collection<Label>> o2)
+            {
+            	int block1 = o1.getKey().blocknum;
+            	int block2 = o2.getKey().blocknum;
+                return block1 - block2;
+            }
+        });
+        for (Map.Entry<Block, Collection<Label>> entry : listOfEntries)
             for (Label target_label : entry.getValue())
             {
                 IBasicBlock target_block = getBlock(target_label);
@@ -259,6 +281,7 @@
     private Block newBlock()
     {
         Block result = new Block();
+        result.blocknum = blocks.size();
         blocks.add(result);
         return result;
     }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/clients/ASC.java b/compiler/src/main/java/org/apache/royale/compiler/clients/ASC.java
index 615ce7c..83e154f 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/clients/ASC.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/clients/ASC.java
@@ -490,6 +490,18 @@
         {
             return removeDeadCode;
         }
+
+		@Override
+		public String getSWFMetadataDate() {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public String getSWFMetadataDateFormat() {
+			// TODO Auto-generated method stub
+			return null;
+		}
     }
     
     private static final int EXIT_CODE_SUCCESS = 0;
diff --git a/compiler/src/main/java/org/apache/royale/compiler/clients/ASDOC.java b/compiler/src/main/java/org/apache/royale/compiler/clients/ASDOC.java
index 07d66f5..24a3b71 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/clients/ASDOC.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/clients/ASDOC.java
@@ -188,6 +188,7 @@
         {
             final ISWCWriter swcWriter = new SWCWriter(outputOptionValue, useCompression,
                     targetSettings.isDebugEnabled(), targetSettings.isTelemetryEnabled(),
+                    targetSettings.getSWFMetadataDate(), targetSettings.getSWFMetadataDateFormat(),
                     SizeReportWritingSWFWriter.getSWFWriterFactory(targetSettings.getSizeReport()));
             swcWriter.write(swc);
             final File outputFile = new File(outputOptionValue);
diff --git a/compiler/src/main/java/org/apache/royale/compiler/clients/COMPC.java b/compiler/src/main/java/org/apache/royale/compiler/clients/COMPC.java
index ef06ba7..c8c320b 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/clients/COMPC.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/clients/COMPC.java
@@ -200,6 +200,7 @@
             	System.out.println("output swc as file");
             final ISWCWriter swcWriter = new SWCWriter(outputOptionValue, useCompression,
                     targetSettings.isDebugEnabled(), targetSettings.isTelemetryEnabled(),
+                    targetSettings.getSWFMetadataDate(), targetSettings.getSWFMetadataDateFormat(),
                     SizeReportWritingSWFWriter.getSWFWriterFactory(targetSettings.getSizeReport()));
             if ((CompilerDiagnosticsConstants.diagnostics & CompilerDiagnosticsConstants.COMPC_PHASES) == CompilerDiagnosticsConstants.COMPC_PHASES)
             	System.out.println("attempting to write swc");
diff --git a/compiler/src/main/java/org/apache/royale/compiler/clients/MXMLC.java b/compiler/src/main/java/org/apache/royale/compiler/clients/MXMLC.java
index 497997e..8c1a971 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/clients/MXMLC.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/clients/MXMLC.java
@@ -121,7 +121,7 @@
         // Therefore the following enum values must be non-negative.
         SUCCESS(0),
         PRINT_HELP(1),
-        FAILED_WITH_PROBLEMS(2),
+        FAILED_WITH_PROBLEMS(0),
         FAILED_WITH_ERRORS(3),
         FAILED_WITH_EXCEPTIONS(4),
         FAILED_WITH_CONFIG_ERRORS(5);
diff --git a/compiler/src/main/java/org/apache/royale/compiler/constants/IMetaAttributeConstants.java b/compiler/src/main/java/org/apache/royale/compiler/constants/IMetaAttributeConstants.java
index dee1690..4aba20b 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/constants/IMetaAttributeConstants.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/constants/IMetaAttributeConstants.java
@@ -210,6 +210,12 @@
     static final String NAME_MIN_VALUE_EXCLUSIVE = "minValueExclusive";
     static final String NAME_MAX_VALUE = "maxValue";
     static final String NAME_MAX_VALUE_EXCLUSIVE = "maxValueExclusive";
+
+    // [RoyaleAbstract]
+    static final String ATTRIBUTE_ABSTRACT = "RoyaleAbstract";
+
+    // [RoyalePrivateConstructor]
+    static final String ATTRIBUTE_PRIVATE_CONSTRUCTOR = "RoyalePrivateConstructor";
 	
 	/**
 	 * List of metadata tags that do not inherit
@@ -222,6 +228,8 @@
 		    ATTRIBUTE_DEPRECATED,
 		    ATTRIBUTE_DISCOURAGED_FOR_PROFILE,
             ATTRIBUTE_EXCLUDECLASS,
+            ATTRIBUTE_ABSTRACT,
+            ATTRIBUTE_PRIVATE_CONSTRUCTOR,
         })));
 }
 
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/abc/ScopedDefinitionTraitsVisitor.java b/compiler/src/main/java/org/apache/royale/compiler/internal/abc/ScopedDefinitionTraitsVisitor.java
index 82d7002..0298127 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/abc/ScopedDefinitionTraitsVisitor.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/abc/ScopedDefinitionTraitsVisitor.java
@@ -256,7 +256,13 @@
             public boolean apply(Namespace ns)
             {
                 return ns.getApiVersion() != ABCConstants.NO_API_VERSION;
-            } }); 
+            }
+            @Override
+            public boolean test(Namespace input)
+            {
+                return apply(input);
+            }
+            }); 
     }
     
     public static String getDefinitionName(Name name)
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/ABCGeneratingReducer.java b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/ABCGeneratingReducer.java
index 5dfb649..b4eb1cf 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/ABCGeneratingReducer.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/ABCGeneratingReducer.java
@@ -72,7 +72,6 @@
 import org.apache.royale.compiler.problems.UnknownContinueTargetProblem;
 import org.apache.royale.compiler.problems.VoidTypeProblem;
 import org.apache.royale.compiler.projects.ICompilerProject;
-import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IASNode;
 import org.apache.royale.compiler.tree.as.IDynamicAccessNode;
 import org.apache.royale.compiler.tree.as.IBinaryOperatorNode;
@@ -6415,7 +6414,8 @@
      */
     private enum XMLContentState { TagStart, TagLiteral, TagName, Attr, ValueNeedsEquals, Value, TagEnd, ContentLiteral, ContentExpression };
 
-    public InstructionList reduce_XMLContent(IASNode iNode, Vector<InstructionList> exprs)
+    @SuppressWarnings("incomplete-switch")
+	public InstructionList reduce_XMLContent(IASNode iNode, Vector<InstructionList> exprs)
     {
         InstructionList result = createInstructionList(iNode);
 
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/ClassDirectiveProcessor.java b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/ClassDirectiveProcessor.java
index cc1fef1..16cfa1e 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/ClassDirectiveProcessor.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/ClassDirectiveProcessor.java
@@ -50,18 +50,24 @@
 import org.apache.royale.compiler.constants.IASKeywordConstants;
 import org.apache.royale.compiler.constants.IASLanguageConstants;
 import org.apache.royale.compiler.constants.IMetaAttributeConstants;
+import org.apache.royale.compiler.constants.INamespaceConstants;
 import org.apache.royale.compiler.definitions.IAccessorDefinition;
 import org.apache.royale.compiler.definitions.IClassDefinition;
 import org.apache.royale.compiler.definitions.IConstantDefinition;
 import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.definitions.IInterfaceDefinition;
+import org.apache.royale.compiler.definitions.INamespaceDefinition;
 import org.apache.royale.compiler.definitions.metadata.IMetaTag;
 import org.apache.royale.compiler.definitions.metadata.IMetaTagAttribute;
+import org.apache.royale.compiler.definitions.references.INamespaceReference;
 import org.apache.royale.compiler.exceptions.CodegenInterruptedException;
+import org.apache.royale.compiler.problems.AbstractOutsideClassProblem;
+import org.apache.royale.compiler.problems.BadAccessAbstractMethodProblem;
 import org.apache.royale.compiler.problems.CircularTypeReferenceProblem;
 import org.apache.royale.compiler.problems.ConstructorCannotHaveReturnTypeProblem;
 import org.apache.royale.compiler.problems.ConstructorIsGetterSetterProblem;
 import org.apache.royale.compiler.problems.ConstructorIsStaticProblem;
+import org.apache.royale.compiler.problems.ConstructorMustBePublicOrPrivateProblem;
 import org.apache.royale.compiler.problems.ConstructorMustBePublicProblem;
 import org.apache.royale.compiler.problems.DuplicateClassDefinitionProblem;
 import org.apache.royale.compiler.problems.DynamicNotOnClassProblem;
@@ -77,6 +83,7 @@
 import org.apache.royale.compiler.problems.OverrideNotFoundProblem;
 import org.apache.royale.compiler.problems.StaticAndOverrideProblem;
 import org.apache.royale.compiler.problems.StaticNamespaceDefinitionProblem;
+import org.apache.royale.compiler.problems.SyntaxProblem;
 import org.apache.royale.compiler.problems.VirtualOutsideClassProblem;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.ASTNodeID;
@@ -85,6 +92,7 @@
 import org.apache.royale.compiler.tree.as.IDefinitionNode;
 import org.apache.royale.compiler.tree.as.IExpressionNode;
 import org.apache.royale.compiler.tree.as.ILanguageIdentifierNode;
+import org.apache.royale.compiler.tree.as.INamespaceDecorationNode;
 import org.apache.royale.compiler.tree.as.ILanguageIdentifierNode.LanguageIdentifierKind;
 import org.apache.royale.compiler.internal.abc.FunctionGeneratorHelper;
 import org.apache.royale.compiler.internal.as.codegen.ICodeGenerator.IConstantValue;
@@ -467,6 +475,7 @@
         initInstructions.addInstruction(OP_initproperty, className);
         
         implementedInterfaceSemanticChecks(class_definition);
+        implementedAbstractClassSemanticChecks(class_definition);
 
         processResourceBundles(class_definition, project, classScope.getProblems());
     }
@@ -956,6 +965,8 @@
 
         FunctionDefinition func = node.getDefinition();
 
+        verifyFunctionNamespace(node, func);
+
         Collection<ICompilerProblem> problems = classScope.getProblems();
 
         // code model has some peculiar ideas about what makes a function a constructor or not
@@ -972,9 +983,21 @@
             // It is ok to omit the namespace
             // We must check the AST, as CM treats all ctors as public no matter what the user typed in
             // so the FunctionDefinition will always be in the public namespace
-            if( node.getActualNamespaceNode() != null &&
-                    node.getActualNamespaceNode().getName() != IASKeywordConstants.PUBLIC)
-                problems.add(new ConstructorMustBePublicProblem(node.getActualNamespaceNode()));
+            if( node.getActualNamespaceNode() != null )
+            {
+                if (classScope.getProject().getAllowPrivateConstructors())
+                {
+                    if (node.getActualNamespaceNode().getName() != IASKeywordConstants.PUBLIC
+                            && !func.isPrivate())
+                    {
+                        problems.add(new ConstructorMustBePublicOrPrivateProblem(node.getActualNamespaceNode()));
+                    }
+                }
+                else if (node.getActualNamespaceNode().getName() != IASKeywordConstants.PUBLIC || func.isPrivate())
+                {
+                    problems.add(new ConstructorMustBePublicProblem(node.getActualNamespaceNode()));
+                }
+            }
 
             // A constructor cannot be static
             if( func.isStatic() )
@@ -1064,37 +1087,131 @@
             }
         }
     }
+    
+    /**
+     * Check the class definition for various errors related to extended
+     * abstract classes, such as making sure that all abstract methods are
+     * implemented
+     * 
+     * @param cls  the class definition to check
+     */
+    void implementedAbstractClassSemanticChecks(ClassDefinition cls)
+    {
+        if(!classScope.getProject().getAllowAbstractClasses())
+        {
+            //don't do these checks if abstract classes aren't enabled
+            return;
+        }
+        if(cls.isAbstract())
+        {
+            // concrete classes don't need to implement abstract methods
+            return;
+        }
+        Iterator<IClassDefinition> it = cls.classIterator(classScope.getProject(), false);
+        while( it.hasNext() )
+        {
+            IClassDefinition otherClass = it.next();
+            if(!otherClass.isAbstract())
+            {
+                //if a subclass is already concrete, then we don't need to check
+                //this class for abstract methods too
+                break;
+            }
+
+            if( otherClass instanceof ClassDefinition && otherClass.isAbstract())
+            {
+                ((ClassDefinition)otherClass).validateClassImplementsAllMethods(classScope.getProject(), cls, classScope.getProblems());
+            }
+        }
+    }
+
+    /**
+    * Verify that abstract function has an appropriate namespace. If it doesn't,
+    * print the appropriate error
+    *
+    * @param func is the function node do be analyzed
+    * @param func_def is the definition for func
+    */
+    private void verifyFunctionNamespace(FunctionNode func, FunctionDefinition func_def)
+    {
+        if(!classScope.getProject().getAllowAbstractClasses())
+        {
+            //if abstract classes aren't allowed, other errors should take
+            //precedence
+            return;
+        }
+
+        if(!func_def.isAbstract())
+        {
+            return;
+        }
+
+        INamespaceDecorationNode nsNode = func.getActualNamespaceNode();
+        
+        // if we have no "actual" node, then there is no namespace in front of our function
+        if (nsNode != null)
+        {
+            if (!INamespaceConstants.internal_.equals(nsNode.getName()))
+            {
+                INamespaceReference ns_ref = func_def.getNamespaceReference();
+                INamespaceDefinition ns_def = ns_ref.resolveNamespaceReference(classScope.getProject());
+                if (ns_def != null && ns_def instanceof INamespaceDefinition.IPrivateNamespaceDefinition)
+                {
+                    classScope.addProblem(new BadAccessAbstractMethodProblem(func));
+                }
+            }
+        }
+    }
+
     /**
      */
     protected void verifyFunctionModifiers(FunctionNode f)
     {
-        ModifiersSet modifiersSet = f.getModifiers();
-        if (modifiersSet == null)
-            return;
-
         IExpressionNode site = f.getNameExpressionNode();
-        if( modifiersSet.hasModifier(ASModifier.STATIC) )
+        IDefinition functionDef = f.getDefinition();
+
+        boolean isStatic = false; //used below
+        ModifiersSet modifiersSet = f.getModifiers();
+        if (modifiersSet != null)
         {
-            if( modifiersSet.hasModifier(ASModifier.FINAL) )
+            isStatic = modifiersSet.hasModifier(ASModifier.STATIC);
+            if(isStatic)
             {
-                classScope.addProblem(new FinalOutsideClassProblem(site) );
+                if( modifiersSet.hasModifier(ASModifier.FINAL) )
+                {
+                    classScope.addProblem(new FinalOutsideClassProblem(site) );
+                }
+                if( modifiersSet.hasModifier(ASModifier.OVERRIDE) )
+                {
+                    classScope.addProblem(new StaticAndOverrideProblem(site) );
+                }
+                if( modifiersSet.hasModifier(ASModifier.DYNAMIC) )
+                {
+                    classScope.addProblem(new DynamicNotOnClassProblem(site) );
+                }
+                if( modifiersSet.hasModifier(ASModifier.VIRTUAL) )
+                {
+                    classScope.addProblem(new VirtualOutsideClassProblem(site) );
+                }
             }
-            if( modifiersSet.hasModifier(ASModifier.OVERRIDE) )
+            classScope.getMethodBodySemanticChecker().checkForDuplicateModifiers(f);
+            // Functions in a class allow all modifiers
+        }
+
+        if (functionDef.isAbstract())
+        {
+            if (classScope.getProject().getAllowAbstractClasses())
             {
-                classScope.addProblem(new StaticAndOverrideProblem(site) );
+                if (!SemanticUtils.canBeAbstract(f, classScope.getProject()))
+                {
+                    classScope.addProblem(new AbstractOutsideClassProblem(site) );
+                }
             }
-            if( modifiersSet.hasModifier(ASModifier.DYNAMIC) )
+            else
             {
-                classScope.addProblem(new DynamicNotOnClassProblem(site) );
-            }
-            if( modifiersSet.hasModifier(ASModifier.VIRTUAL) )
-            {
-                classScope.addProblem(new VirtualOutsideClassProblem(site) );
+                classScope.addProblem(new SyntaxProblem(site, IASKeywordConstants.ABSTRACT));
             }
         }
-        classScope.getMethodBodySemanticChecker().checkForDuplicateModifiers(f);
-        // Functions in a class allow all modifiers
-        return;
     }
 
     protected void verifyVariableModifiers(VariableNode v)
@@ -1127,6 +1244,17 @@
             {
                 classScope.addProblem(new VirtualOutsideClassProblem(site));
             }
+            else if( modifier == ASModifier.ABSTRACT )
+            {
+                if(classScope.getProject().getAllowAbstractClasses())
+                {
+                    classScope.addProblem(new AbstractOutsideClassProblem(site));
+                }
+                else
+                {
+                    classScope.addProblem(new SyntaxProblem(site, IASKeywordConstants.ABSTRACT));
+                }
+            }
         }
         classScope.getMethodBodySemanticChecker().checkForDuplicateModifiers(v);
     }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/DirectiveProcessor.java b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/DirectiveProcessor.java
index d199a88..c052318 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/DirectiveProcessor.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/DirectiveProcessor.java
@@ -23,7 +23,6 @@
 
 
 
-import org.apache.royale.abc.instructionlist.InstructionList;
 import org.apache.royale.compiler.internal.definitions.FunctionDefinition;
 import org.apache.royale.compiler.internal.tree.as.ClassNode;
 import org.apache.royale.compiler.internal.tree.as.FunctionNode;
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/GlobalDirectiveProcessor.java b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/GlobalDirectiveProcessor.java
index 0f4f3c8..7f28031 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/GlobalDirectiveProcessor.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/GlobalDirectiveProcessor.java
@@ -30,6 +30,7 @@
 import org.apache.royale.compiler.tree.as.IExpressionNode;
 import org.apache.royale.compiler.common.ASModifier;
 import org.apache.royale.compiler.common.ModifiersSet;
+import org.apache.royale.compiler.constants.IASKeywordConstants;
 import org.apache.royale.compiler.constants.IMetaAttributeConstants;
 import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.internal.definitions.ClassDefinition;
@@ -45,6 +46,7 @@
 import org.apache.royale.compiler.internal.tree.as.PackageNode;
 import org.apache.royale.compiler.internal.tree.as.VariableNode;
 import org.apache.royale.compiler.internal.tree.mxml.MXMLDocumentNode;
+import org.apache.royale.compiler.problems.AbstractOutsideClassProblem;
 import org.apache.royale.compiler.problems.DynamicNotOnClassProblem;
 import org.apache.royale.compiler.problems.EmbedOnlyOnClassesAndVarsProblem;
 import org.apache.royale.compiler.problems.FinalOutsideClassProblem;
@@ -54,6 +56,7 @@
 import org.apache.royale.compiler.problems.NativeVariableProblem;
 import org.apache.royale.compiler.problems.OverrideOutsideClassProblem;
 import org.apache.royale.compiler.problems.StaticOutsideClassProblem;
+import org.apache.royale.compiler.problems.SyntaxProblem;
 import org.apache.royale.compiler.problems.VirtualOutsideClassProblem;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.mxml.IMXMLDocumentNode;
@@ -320,30 +323,47 @@
      */
     protected void verifyClassModifiers(ClassNode c)
     {
-        ModifiersSet modifiersSet = c.getModifiers();
-        if (modifiersSet == null)
-            return;
-
-        ASModifier[] modifiers = modifiersSet.getAllModifiers();
         IExpressionNode site = c.getNameExpressionNode();
-        for (ASModifier modifier : modifiers)
+
+        ModifiersSet modifiersSet = c.getModifiers();
+        if (modifiersSet != null)
         {
-            // final allowed on a class
-            if( modifier == ASModifier.FINAL || modifier == ASModifier.DYNAMIC)
+            ASModifier[] modifiers = modifiersSet.getAllModifiers();
+            for (ASModifier modifier : modifiers)
             {
-                continue;
+                // final, dynamic, and abstract allowed on a class
+                if( modifier == ASModifier.FINAL || modifier == ASModifier.DYNAMIC || modifier == ASModifier.ABSTRACT)
+                {
+                    continue;
+                }
+                // native generates different error for class/interface
+                else if (modifier == ASModifier.NATIVE)
+                {
+                    currentScope.addProblem(new NativeNotOnFunctionProblem(site) );
+                }
+                else
+                {
+                    verifyModifier(site, modifier);
+                }
             }
-            // native generates different error for class/interface
-            else if (modifier == ASModifier.NATIVE)
+            currentScope.getMethodBodySemanticChecker().checkForDuplicateModifiers(c);
+        }
+
+        IDefinition classDef = c.getDefinition();
+        if (classDef.isAbstract())
+        {
+            if (currentScope.getProject().getAllowAbstractClasses())
             {
-                currentScope.addProblem(new NativeNotOnFunctionProblem(site) );
+                if(!SemanticUtils.canBeAbstract(c, currentScope.getProject()))
+                {
+                    currentScope.addProblem(new AbstractOutsideClassProblem(site) );
+                }
             }
             else
             {
-                verifyModifier(site, modifier);
+                currentScope.addProblem(new SyntaxProblem(site, IASKeywordConstants.ABSTRACT));
             }
         }
-        currentScope.getMethodBodySemanticChecker().checkForDuplicateModifiers(c);
     }
 
     /**
@@ -408,6 +428,17 @@
             currentScope.addProblem(new OverrideOutsideClassProblem(site));
         else if( modifier == ASModifier.VIRTUAL )
             currentScope.addProblem(new VirtualOutsideClassProblem(site));
+        else if( modifier == ASModifier.ABSTRACT )
+        {
+            if(currentScope.getProject().getAllowAbstractClasses())
+            {
+                currentScope.addProblem(new AbstractOutsideClassProblem(site));
+            }
+            else
+            {
+                currentScope.addProblem(new SyntaxProblem(site, IASKeywordConstants.ABSTRACT));
+            }
+        }
     }
 
     /**
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/InlineFunctionLexicalScope.java b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/InlineFunctionLexicalScope.java
index c53032a..395c02e 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/InlineFunctionLexicalScope.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/InlineFunctionLexicalScope.java
@@ -121,7 +121,7 @@
         {
             String paramName = params[i].getBaseName();
             Binding paramBinding = getBinding(params[i]);
-            if (paramBinding != null && !uniqueParamNames.contains(paramBinding))
+            if (paramBinding != null && !uniqueParamNames.contains(paramName))
             {
                 result.addInstruction(paramBinding.setlocal());
                 uniqueParamNames.add(paramName);
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/InterfaceDirectiveProcessor.java b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/InterfaceDirectiveProcessor.java
index 2177b77..e8409c3 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/InterfaceDirectiveProcessor.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/InterfaceDirectiveProcessor.java
@@ -38,6 +38,7 @@
 import org.apache.royale.compiler.common.ASModifier;
 import org.apache.royale.compiler.common.IMetaInfo;
 import org.apache.royale.compiler.common.ModifiersSet;
+import org.apache.royale.compiler.constants.IASKeywordConstants;
 import org.apache.royale.compiler.constants.INamespaceConstants;
 import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.definitions.IInterfaceDefinition;
@@ -55,6 +56,7 @@
 import org.apache.royale.compiler.internal.tree.as.InterfaceNode;
 import org.apache.royale.compiler.internal.tree.as.NamespaceIdentifierNode;
 import org.apache.royale.compiler.internal.tree.as.VariableNode;
+import org.apache.royale.compiler.problems.AbstractOutsideClassProblem;
 import org.apache.royale.compiler.problems.AmbiguousReferenceProblem;
 import org.apache.royale.compiler.problems.CannotExtendClassProblem;
 import org.apache.royale.compiler.problems.ConstructorInInterfaceProblem;
@@ -67,6 +69,7 @@
 import org.apache.royale.compiler.problems.NamespaceInInterfaceProblem;
 import org.apache.royale.compiler.problems.NativeUsedInInterfaceProblem;
 import org.apache.royale.compiler.problems.StaticOutsideClassProblem;
+import org.apache.royale.compiler.problems.SyntaxProblem;
 import org.apache.royale.compiler.problems.UnknownInterfaceProblem;
 import org.apache.royale.compiler.problems.BadAccessInterfaceMemberProblem;
 import org.apache.royale.compiler.problems.InterfaceNamespaceAttributeProblem;
@@ -347,6 +350,8 @@
 
         // Warn if there is no return type
         SemanticUtils.checkReturnValueHasNoTypeDeclaration(interfaceScope, func, func_def);
+        // Warn if there are any missing parameter types
+        SemanticUtils.checkParametersHaveNoTypeDeclaration(interfaceScope, func, func_def);
 
         // Interface methods can't have a body
         if( func.hasBody() )
@@ -426,40 +431,54 @@
      */
     protected void verifyFunctionModifiers(FunctionNode f)
     {
-        ModifiersSet modifiersSet = f.getModifiers();
-        if (modifiersSet == null)
-            return;
-
-        ASModifier[] modifiers = modifiersSet.getAllModifiers();
         IExpressionNode site = f.getNameExpressionNode();
-        for (ASModifier modifier : modifiers)
+
+        ModifiersSet modifiersSet = f.getModifiers();
+        if (modifiersSet != null)
         {
-            if( modifier == ASModifier.STATIC )
+            ASModifier[] modifiers = modifiersSet.getAllModifiers();
+            for (ASModifier modifier : modifiers)
             {
-                this.interfaceScope.addProblem(new StaticOutsideClassProblem(site));
+                if( modifier == ASModifier.STATIC )
+                {
+                    this.interfaceScope.addProblem(new StaticOutsideClassProblem(site));
+                }
+                else if ( modifier == ASModifier.OVERRIDE )
+                {
+                    interfaceScope.addProblem(new InvalidOverrideProblem(site));
+                }
+                else if( modifier == ASModifier.FINAL )
+                {
+                    interfaceScope.addProblem(new FinalOutsideClassProblem(site));
+                }
+                else if( modifier == ASModifier.NATIVE )
+                {
+                    interfaceScope.addProblem(new NativeUsedInInterfaceProblem(site));
+                }
+                else if( modifier == ASModifier.VIRTUAL )
+                {
+                    interfaceScope.addProblem(new VirtualOutsideClassProblem(site));
+                }
+                else if ( modifier == ASModifier.DYNAMIC )
+                {
+                    //  Allow this and continue.
+                }
             }
-            else if ( modifier == ASModifier.OVERRIDE )
+            interfaceScope.getMethodBodySemanticChecker().checkForDuplicateModifiers(f);
+        }
+
+        IDefinition functionDef = f.getDefinition();
+        if (functionDef.isAbstract())
+        {
+            if (interfaceScope.getProject().getAllowAbstractClasses())
             {
-                interfaceScope.addProblem(new InvalidOverrideProblem(site));
+                interfaceScope.addProblem(new AbstractOutsideClassProblem(site));
             }
-            else if( modifier == ASModifier.FINAL )
+            else
             {
-                interfaceScope.addProblem(new FinalOutsideClassProblem(site));
-            }
-            else if( modifier == ASModifier.NATIVE )
-            {
-                interfaceScope.addProblem(new NativeUsedInInterfaceProblem(site));
-            }
-            else if( modifier == ASModifier.VIRTUAL )
-            {
-                interfaceScope.addProblem(new VirtualOutsideClassProblem(site));
-            }
-            else if ( modifier == ASModifier.DYNAMIC )
-            {
-                //  Allow this and continue.
+                interfaceScope.addProblem(new SyntaxProblem(site, IASKeywordConstants.ABSTRACT));
             }
         }
-        interfaceScope.getMethodBodySemanticChecker().checkForDuplicateModifiers(f);
     }
 
     /**
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/LabelScopeControlFlowContext.java b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/LabelScopeControlFlowContext.java
index 29b6ce8..a01549f 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/LabelScopeControlFlowContext.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/LabelScopeControlFlowContext.java
@@ -72,7 +72,8 @@
      * @param labelMap Map to populate with found labels
      * @param node Node to search from.
      */
-    private static void populateLabelMap(Multimap<String, LabeledStatementNode> labelMap, IASNode node)
+    @SuppressWarnings("incomplete-switch")
+	private static void populateLabelMap(Multimap<String, LabeledStatementNode> labelMap, IASNode node)
     {
         ASTNodeID nodeID = node.getNodeID();
         
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/MXMLClassDirectiveProcessor.java b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/MXMLClassDirectiveProcessor.java
index b92da21..01adf85 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/MXMLClassDirectiveProcessor.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/MXMLClassDirectiveProcessor.java
@@ -2852,6 +2852,11 @@
         {
             return node instanceof IMXMLInstanceNode;
         }
+        @Override
+        public boolean test(IASNode input)
+        {
+            return apply(input);
+        }
     };
 
     /**
@@ -2864,6 +2869,11 @@
         {
             return node instanceof IMXMLSpecifierNode;
         }
+        @Override
+        public boolean test(IASNode input)
+        {
+            return apply(input);
+        }
     };
     
     /**
@@ -4355,7 +4365,8 @@
      * based on the instances, properties, styles, and events
      * that depend on the state.
      */
-    void processMXMLState(IMXMLStateNode stateNode, Context context)
+    @SuppressWarnings("incomplete-switch")
+	void processMXMLState(IMXMLStateNode stateNode, Context context)
     {
         int numElements = 1;
         if (getProject().getTargetSettings().getMxmlChildrenAsData())
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/clients/CLIFactory.java b/compiler/src/main/java/org/apache/royale/compiler/internal/clients/CLIFactory.java
index 48cad1b..d09c164 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/clients/CLIFactory.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/clients/CLIFactory.java
@@ -48,7 +48,7 @@
      * 
      * @return Apache Common CLI options
      */
-    @SuppressWarnings("static")
+    @SuppressWarnings({ "static-access" })
     public static Options getOptionsForASC()
     {
         if (ascOptions != null)
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/codegen/databinding/BindingDatabase.java b/compiler/src/main/java/org/apache/royale/compiler/internal/codegen/databinding/BindingDatabase.java
index 186d602..43d392c 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/codegen/databinding/BindingDatabase.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/codegen/databinding/BindingDatabase.java
@@ -317,7 +317,8 @@
        return ret;
     }
     
-    private boolean objIsType(WatcherInfoBase obj, WatcherType type)
+    @SuppressWarnings("incomplete-switch")
+	private boolean objIsType(WatcherInfoBase obj, WatcherType type)
     {
         boolean ret = false;
         
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/codegen/databinding/BindingDestinationMaker.java b/compiler/src/main/java/org/apache/royale/compiler/internal/codegen/databinding/BindingDestinationMaker.java
index add3260..6ffc3fa 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/codegen/databinding/BindingDestinationMaker.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/codegen/databinding/BindingDestinationMaker.java
@@ -31,14 +31,21 @@
 import org.apache.royale.compiler.internal.as.codegen.InstructionListNode;
 import org.apache.royale.compiler.internal.as.codegen.MXMLClassDirectiveProcessor;
 import org.apache.royale.compiler.internal.definitions.NamespaceDefinition;
+import org.apache.royale.compiler.internal.tree.as.DynamicAccessNode;
+import org.apache.royale.compiler.internal.tree.as.IdentifierNode;
+import org.apache.royale.compiler.internal.tree.as.NodeBase;
+import org.apache.royale.compiler.internal.tree.as.NumericLiteralNode;
 import org.apache.royale.compiler.tree.as.IASNode;
 import org.apache.royale.compiler.tree.as.IExpressionNode;
+import org.apache.royale.compiler.tree.mxml.IMXMLArrayNode;
+import org.apache.royale.compiler.tree.mxml.IMXMLConcatenatedDataBindingNode;
 import org.apache.royale.compiler.tree.mxml.IMXMLDataBindingNode;
 import org.apache.royale.compiler.tree.mxml.IMXMLModelNode;
 import org.apache.royale.compiler.tree.mxml.IMXMLModelPropertyNode;
 import org.apache.royale.compiler.tree.mxml.IMXMLModelRootNode;
 import org.apache.royale.compiler.tree.mxml.IMXMLPropertySpecifierNode;
 import org.apache.royale.compiler.tree.mxml.IMXMLSingleDataBindingNode;
+import org.apache.royale.compiler.tree.mxml.IMXMLStringNode;
 
 /**
  * Utility class for analyze binding destinations and making
@@ -144,6 +151,42 @@
                 }
             }
         }
+        else if (parent instanceof IMXMLStringNode && dbnode instanceof IMXMLConcatenatedDataBindingNode)
+        {
+        	// this is a binding in a literal like a string, such as 'this is {SOME_VAR} times';
+        	// we need to figure out how to set the evaluated value.
+        	// if this binding is not in an array, then other code will use the effectiveID of the string
+        	// and set the value.
+        	// if it is in an array, then figure out the index in the array to set
+        	if (parent.getParent() instanceof IMXMLArrayNode)
+        	{
+        		int index = -1;
+        		int n = parent.getParent().getChildCount();
+        		for (int i = 0; i < n; i++)
+        		{
+        			IASNode child = parent.getParent().getChild(i);
+        			if (child == parent)
+        			{
+        				index = i;
+        				break;
+        			}
+        		}
+        		IdentifierNode arrayNode = new IdentifierNode(((IMXMLArrayNode)parent.getParent()).getEffectiveID());
+        		arrayNode.setSourcePath(parent.getSourcePath());
+        		arrayNode.setColumn(parent.getColumn());
+        		arrayNode.setLine(parent.getLine());
+        		NumericLiteralNode indexNode = new NumericLiteralNode(new Integer(index).toString());
+        		indexNode.setSourcePath(parent.getSourcePath());
+        		indexNode.setColumn(parent.getColumn());
+        		indexNode.setLine(parent.getLine());
+        		DynamicAccessNode mae = new DynamicAccessNode(arrayNode);
+        		mae.setRightOperandNode(indexNode);
+        		mae.setParent((NodeBase) dbnode.getParent());
+        		arrayNode.setParent(mae);
+        		indexNode.setParent(mae);
+        		return mae;
+        	}
+        }
         return ret;   
     }
     
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/config/RoyaleTargetSettings.java b/compiler/src/main/java/org/apache/royale/compiler/internal/config/RoyaleTargetSettings.java
index e3d966c..414eed6 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/config/RoyaleTargetSettings.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/config/RoyaleTargetSettings.java
@@ -22,23 +22,15 @@
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
-import java.util.TreeMap;
 
-import org.apache.commons.io.FileUtils;
 
 import org.apache.royale.compiler.config.Configuration;
 import org.apache.royale.compiler.config.Configurator;
-import org.apache.royale.compiler.config.RSLSettings;
 import org.apache.royale.compiler.internal.projects.LibraryPathManager;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.projects.IRoyaleProject;
-import org.apache.royale.compiler.targets.ITargetSettings;
-import org.apache.royale.utils.FilenameNormalization;
-import com.google.common.collect.ImmutableList;
 
 /**
  * Value object of ITargetSettings.
@@ -72,4 +64,14 @@
 
         return externalLibraryPath;
     }
+    
+    @Override
+    public File getLinkReport()
+    {
+    	if (project != null)
+    		return ((IRoyaleProject)project).getLinkReport(configuration);
+    	
+        return super.getLinkReport();
+    }
+
 }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSKeyFrames.java b/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSKeyFrames.java
index abc1da1..4708e57 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSKeyFrames.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSKeyFrames.java
@@ -48,7 +48,8 @@
 
     private final String id;
 
-    @Override
+    @SuppressWarnings("incomplete-switch")
+	@Override
     public String toString()
     {
         final StringBuilder result = new StringBuilder();
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSProperty.java b/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSProperty.java
index 9b3ddf1..0f4c0a2 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSProperty.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSProperty.java
@@ -57,7 +57,7 @@
     @Override
     public String toString()
     {
-        if (rawName.equalsIgnoreCase("border"))
+        if (rawName.equalsIgnoreCase("border") && value instanceof CSSArrayPropertyValue)
         {
             CSSArrayPropertyValue borderValues = (CSSArrayPropertyValue)value;
             return String.format("%s: %s;", rawName, Joiner.on(" ").join(borderValues.getElements()));
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/css/codegen/CSSCompilationSession.java b/compiler/src/main/java/org/apache/royale/compiler/internal/css/codegen/CSSCompilationSession.java
index a9599e5..09ff971 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/css/codegen/CSSCompilationSession.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/css/codegen/CSSCompilationSession.java
@@ -166,11 +166,6 @@
     private boolean keepAllTypeSelectors;
 
     /**
-     * Excluded CSS files.
-     */
-    private List<String> excludedCSSFiles;
-
-    /**
      * Determine if a rule should be in the output
      * 
      * @return true if rule should be in the output
@@ -421,14 +416,4 @@
         this.keepAllTypeSelectors = keepAllTypeSelectors;
     }
 
-    /**
-     * Set whether to keep all type selectors for linking.
-     * 
-     * @param keepAllTypeSelectors value
-     */
-    public void setExcludeDefaultsCSSFiles(List<String> excludes)
-    {
-        this.excludedCSSFiles = excludes;
-    }
-
 }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/css/semantics/CSSSemanticAnalyzer.java b/compiler/src/main/java/org/apache/royale/compiler/internal/css/semantics/CSSSemanticAnalyzer.java
index b0f1f91..6573c57 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/css/semantics/CSSSemanticAnalyzer.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/css/semantics/CSSSemanticAnalyzer.java
@@ -406,6 +406,13 @@
             }
             return false;
         }
+        
+        @Override
+        public boolean test(ICSSRule input)
+        {
+            return apply(input);
+        }
+
     }
 
     /**
@@ -447,6 +454,12 @@
             }
             return true;
         }
+        
+        @Override
+        public boolean test(ICSSRule input)
+        {
+            return apply(input);
+        }
     }
 
     /**
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/AmbiguousDefinition.java b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/AmbiguousDefinition.java
index b51b8c5..91e0d5e 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/AmbiguousDefinition.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/AmbiguousDefinition.java
@@ -95,10 +95,11 @@
      * 
      * @param project The Project to use to resolve things
      * @param defs an Array of definitions to compare
+     * @param favorTypes 
      * @return the definition to use as the result of the lookup, if the
      * ambiguity was successfully resolved, otherwise null
      */
-    public static IDefinition resolveAmbiguities(ICompilerProject project, List<IDefinition> defs)
+    public static IDefinition resolveAmbiguities(ICompilerProject project, List<IDefinition> defs, boolean favorTypes)
     {
         IDefinition resolvedDef = null;
 
@@ -111,6 +112,26 @@
             resolvedDef = defs.get(0);
         }
 
+        // this is used to favor type definitions over function definitions
+        // when resolving the type of a variable (which can't be a function)
+        if (resolvedDef == null && defs.size() == 2)
+        {
+        	IDefinition def0 = defs.get(0);
+        	IDefinition def1 = defs.get(1);
+        	if (def0 instanceof FunctionDefinition &&
+        			(def1 instanceof ClassDefinition ||
+        			(def1 instanceof InterfaceDefinition)))
+        	{
+        		resolvedDef = favorTypes ? def1 : def0;
+        	}
+        	else if (def1 instanceof FunctionDefinition &&
+        			(def0 instanceof ClassDefinition ||
+        			(def0 instanceof InterfaceDefinition)))
+        	{
+        		resolvedDef = favorTypes ? def0 : def1;
+        	}
+        }
+        
         if (resolvedDef == null)
         {
             // check for redeclared variables and functions
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinition.java b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinition.java
index eb59a7b..85a6900 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinition.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinition.java
@@ -39,6 +39,7 @@
 import org.apache.royale.compiler.constants.IASLanguageConstants;
 import org.apache.royale.compiler.constants.IMetaAttributeConstants;
 import org.apache.royale.compiler.constants.IASLanguageConstants.BuiltinType;
+import org.apache.royale.compiler.definitions.IAccessorDefinition;
 import org.apache.royale.compiler.definitions.IClassDefinition;
 import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.definitions.IEffectDefinition;
@@ -74,6 +75,7 @@
 import org.apache.royale.compiler.problems.MissingSkinStateProblem;
 import org.apache.royale.compiler.problems.OnlyOneHostComponentAllowedProblem;
 import org.apache.royale.compiler.problems.SkinPartsMustBePublicProblem;
+import org.apache.royale.compiler.problems.UnimplementedAbstractMethodProblem;
 import org.apache.royale.compiler.problems.WrongSkinPartProblem;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.scopes.IASScope;
@@ -311,6 +313,16 @@
     protected void setConstructor(IFunctionDefinition constructor)
     {
         this.constructor = constructor;
+
+        if(this.constructor.isPrivate()
+                && this.constructor.getMetaTagByName(IMetaAttributeConstants.ATTRIBUTE_PRIVATE_CONSTRUCTOR) == null)
+        {
+            // ensures that the constructor remains private when compiled into
+            // a library because the metadata is how private constructors are
+            // stored in the bytecode
+            MetaTag privateMetaTag = new MetaTag(this, IMetaAttributeConstants.ATTRIBUTE_PRIVATE_CONSTRUCTOR, new IMetaTagAttribute[0]);
+            addMetaTag(privateMetaTag);
+        }
     }
 
     @Override
@@ -756,20 +768,27 @@
     {
         Set<String> states = new HashSet<String>();
 
-        // Iterate over this class and its superclasses.
-        for (IClassDefinition c : classIterable(project, true))
+        // Iterate over the superclasses first, but don't worry about duplicates
+        // yet. The superclasses will find their own duplicates!
+        for (IClassDefinition c : classIterable(project, false))
         {
             for (String state : c.getSkinStates(problems))
             {
-                if (states.contains(state))
-                {
-                    ICompilerProblem problem = new DuplicateSkinStateProblem(c, state);
-                    problems.add(problem);
-                }
-
                 states.add(state);
             }
         }
+        // Then, add the states from this class and check for duplicates that
+        // specifically come from this class
+        for (String state : getSkinStates(problems))
+        {
+            if (states.contains(state))
+            {
+                ICompilerProblem problem = new DuplicateSkinStateProblem(this, state);
+                problems.add(problem);
+            }
+
+            states.add(state);
+        }
 
         return states.toArray(new String[states.size()]);
     }
@@ -1455,4 +1474,61 @@
         // Some implicit class definition we have never seen before.
         return false;
     }
+
+    /**
+     * Method to find all the abstract methods declared in this class, and
+     * validate that the concrete class definition passed in implements those
+     * methods, and that they are implemented with compatible signatures
+     * 
+     * @param cls the class definition to check
+     * @param problems a list of problems to report errors to
+     */
+    public void validateClassImplementsAllMethods(ICompilerProject project, ClassDefinition cls, Collection<ICompilerProblem> problems)
+    {
+        ASScope classScope = cls.getContainedScope();
+
+        for (IDefinitionSet defSet : this.getContainedScope().getAllLocalDefinitionSets())
+        {
+            for (int i = 0, l = defSet.getSize(); i < l; ++i)
+            {
+                IDefinition def = defSet.getDefinition(i);
+                if (def instanceof FunctionDefinition && !(def instanceof IAccessorDefinition))
+                {
+                    FunctionDefinition abstractMethod = (FunctionDefinition)def;
+
+                    // Skip any implicit methods added for CM compat
+                    if (abstractMethod.isImplicit())
+                        continue;
+
+                    // Skip the constructor method of the interface.
+                    if (abstractMethod.getBaseName().equals(getBaseName()))
+                        continue;
+
+                    // Skip methods that are static
+                    if (abstractMethod.isStatic())
+                        continue;
+
+                    // Skip methods that aren't abstract
+                    if (!abstractMethod.isAbstract())
+                        continue;
+
+                    INamespaceDefinition ns = abstractMethod.resolveNamespace(project);
+                    if(ns instanceof INamespaceDefinition.IProtectedNamespaceDefinition)
+                    {
+                        ns = cls.getProtectedNamespaceReference();
+                    }
+
+                    IDefinition c = classScope.getQualifiedPropertyFromDef(project, cls, abstractMethod.getBaseName(), ns, false);
+                    if (c == null || c.isAbstract())
+                    {
+                        // Error, didn't implement the method
+                        problems.add(new UnimplementedAbstractMethodProblem(cls,
+                                abstractMethod.getBaseName(),
+                                this.getBaseName(),
+                                cls.getBaseName()));
+                    }
+                }
+            }
+        }
+    }
 }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinitionBase.java b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinitionBase.java
index fd595e7..2dcf3ed 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinitionBase.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinitionBase.java
@@ -32,8 +32,10 @@
 import org.apache.royale.compiler.definitions.IInterfaceDefinition;
 import org.apache.royale.compiler.definitions.ITypeDefinition;
 import org.apache.royale.compiler.definitions.metadata.IMetaTag;
+import org.apache.royale.compiler.definitions.metadata.IMetaTagAttribute;
 import org.apache.royale.compiler.definitions.references.IReference;
 import org.apache.royale.compiler.internal.as.codegen.BindableHelper;
+import org.apache.royale.compiler.internal.definitions.metadata.MetaTag;
 import org.apache.royale.compiler.internal.projects.CompilerProject;
 import org.apache.royale.compiler.internal.scopes.ASProjectScope;
 import org.apache.royale.compiler.internal.scopes.ASScope;
@@ -427,7 +429,23 @@
 
         if (type instanceof IClassDefinition)
         {
-        	if (baseDefinitions == null)
+            if (!getPerformanceCachingEnabled())
+            {
+                baseDefinitions = null;
+
+                // We're trying to determine whether this class
+                // is derived from a specified class ('type').
+                // Iterate the superclass chain looking for 'type'.
+                Iterator<IClassDefinition> iter = classIterator(project, false);
+                while (iter.hasNext())
+                {
+                    IClassDefinition cls = iter.next();
+                    if (cls == type)
+                        return true;
+                }
+                return false;
+            }
+        	else if (baseDefinitions == null)
         	{
             	if ((CompilerDiagnosticsConstants.diagnostics & CompilerDiagnosticsConstants.CLASS_DEFINITION_BASE) == CompilerDiagnosticsConstants.CLASS_DEFINITION_BASE)
             		System.out.println("ClassDefinitionBase waiting for lock for " + this.getQualifiedName());
@@ -456,7 +474,24 @@
         }
         else if (type instanceof IInterfaceDefinition)
         {
-        	if (implDefinitions == null)
+            if (!getPerformanceCachingEnabled())
+            {
+                implDefinitions = null;
+
+                // We're trying to determine whether this class
+                // implements a specified interface ('type').
+                // Iterate all of the interfaces that this class implements,
+                // looking for 'type'.
+                Iterator<IInterfaceDefinition> iter = interfaceIterator(project);
+                while (iter.hasNext())
+                {
+                    IInterfaceDefinition intf = iter.next();
+                    if (intf == type)
+                        return true;
+                }
+                return false;
+            }
+        	else if (implDefinitions == null)
         	{
             	if ((CompilerDiagnosticsConstants.diagnostics & CompilerDiagnosticsConstants.CLASS_DEFINITION_BASE) == CompilerDiagnosticsConstants.CLASS_DEFINITION_BASE)
             		System.out.println("ClassDefinitionBase waiting for lock for " + this.getQualifiedName());
@@ -503,6 +538,30 @@
         return interfaces;
     }
 
+    @Override
+    public boolean isAbstract()
+    {
+        if(super.isAbstract())
+        {
+            return true;
+        }
+        IMetaTag[] metaTags = getMetaTagsByName(IMetaAttributeConstants.ATTRIBUTE_ABSTRACT);
+        return metaTags != null && metaTags.length > 0;
+    }
+
+    /**
+     * Utility to mark a definition as abstract. This method should only ever be
+     * called during construction or initialization of a definition.
+     */
+    @Override
+    public void setAbstract()
+    {
+        super.setAbstract();
+
+        MetaTag abstractMetaTag = new MetaTag(this, IMetaAttributeConstants.ATTRIBUTE_ABSTRACT, new IMetaTagAttribute[0]);
+        addMetaTag(abstractMetaTag);
+    }
+
     /*
      * This inner class implements an iterator that enumerates all of this
      * ClassDefinition's superclasses. <p> It will stop iterating when it
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/DefinitionBase.java b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/DefinitionBase.java
index de6bdbc..50a4951 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/DefinitionBase.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/DefinitionBase.java
@@ -108,6 +108,18 @@
     protected static final short FLAG_DEPRECATED = 1 << 13;
     protected static final short FLAG_DECLARED_IN_CONTROL_FLOW = 1 << 14;
 
+    private static boolean performanceCachingEnabled = false;
+
+    public static boolean getPerformanceCachingEnabled()
+    {
+        return performanceCachingEnabled;
+    }
+
+    public static void setPerformanceCachingEnabled(boolean enable)
+    {
+        performanceCachingEnabled = enable;
+    }
+
     /**
      * Constructor.
      * 
@@ -243,7 +255,7 @@
     @Override
     public IDefinition getParent()
     {
-    	if (parentDef != null)
+    	if (getPerformanceCachingEnabled() && parentDef != null)
     		return parentDef;
     	
         IASScope scope = getContainingScope();
@@ -257,8 +269,10 @@
         while ((scope != null) && (scope.getDefinition() == null))
             scope = scope.getContainingScope();
 
-        parentDef = scope != null ? scope.getDefinition() : null;
-        return parentDef;
+        IDefinition result = scope != null ? scope.getDefinition() : null;
+        if (getPerformanceCachingEnabled())
+            parentDef = result;
+        return result;
     }
 
     @Override
@@ -535,6 +549,12 @@
     private static DefinitionBase getContainingToplevelDefinition(DefinitionBase definition)
     {
         ASScope currentContainingScope = definition.getContainingASScope();
+        if (currentContainingScope == null)
+        {
+            // With some synthetic definitions you can't find a containint top level definition.
+            // This happens with Vector<T>, for example. In this case, return null
+            return null;
+        }
         DefinitionBase currentDefinition = definition;
 
         IScopedDefinition containingDefinition = currentContainingScope.getContainingDefinition();
@@ -543,10 +563,11 @@
             currentDefinition = (DefinitionBase)containingDefinition;
             currentContainingScope = currentDefinition.getContainingASScope();
             
-            // With some synthetic definitions you can't find a containint top level definition.
-            // This happens with Vector<T>, for example. In this case, return null
             if (currentContainingScope == null)
-                return null;                    
+            {
+                // See comment above
+                return null;
+            }
             
             containingDefinition = currentContainingScope.getContainingDefinition();
         }
@@ -687,6 +708,21 @@
         flags |= FLAG_STATIC;
     }
 
+    // instead of increasing the size of "flags" from a short to int, I added
+    // a boolean variable instead. feel free to change this, if desired. -JT
+    private boolean abstractFlag = false;
+
+    @Override
+    public boolean isAbstract()
+    {
+        return abstractFlag;
+    }
+
+    public void setAbstract()
+    {
+        abstractFlag = true;
+    }
+
     @Override
     public boolean hasModifier(ASModifier modifier)
     {
@@ -717,6 +753,10 @@
             // Ignore "virtual" modifier.
             return false;
         }
+        else if (modifier == ASModifier.ABSTRACT)
+        {
+            return abstractFlag;
+        }
         else
         {
             assert false : "Unknown modifier: " + modifier;
@@ -738,6 +778,8 @@
             result.addModifier(ASModifier.DYNAMIC);
         if ((flags & FLAG_NATIVE) != 0)
             result.addModifier(ASModifier.NATIVE);
+        if (abstractFlag)
+            result.addModifier(ASModifier.ABSTRACT);
         return result;
     }
 
@@ -760,6 +802,9 @@
         else if (modifier == ASModifier.NATIVE)
             flags |= FLAG_NATIVE;
 
+        else if (modifier == ASModifier.ABSTRACT)
+            setAbstract();
+
         else
             assert false;
     }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/FunctionDefinition.java b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/FunctionDefinition.java
index fdcbf80..9f0e546 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/FunctionDefinition.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/FunctionDefinition.java
@@ -41,9 +41,10 @@
 import org.apache.royale.compiler.definitions.ITypeDefinition;
 import org.apache.royale.compiler.definitions.references.INamespaceReference;
 import org.apache.royale.compiler.definitions.metadata.IMetaTag;
+import org.apache.royale.compiler.definitions.metadata.IMetaTagAttribute;
 import org.apache.royale.compiler.definitions.references.IReference;
+import org.apache.royale.compiler.internal.definitions.metadata.MetaTag;
 import org.apache.royale.compiler.internal.projects.CompilerProject;
-import org.apache.royale.compiler.problems.AmbiguousReferenceProblem;
 import org.apache.royale.compiler.problems.ConflictingDefinitionProblem;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.scopes.IASScope;
@@ -271,6 +272,53 @@
     }
 
     @Override
+    public boolean isAbstract()
+    {
+        if(super.isAbstract())
+        {
+            return true;
+        }
+        IMetaTag[] metaTags = getMetaTagsByName(IMetaAttributeConstants.ATTRIBUTE_ABSTRACT);
+        return metaTags != null && metaTags.length > 0;
+    }
+
+    /**
+     * Utility to mark a definition as abstract. This method should only ever be
+     * called during construction or initialization of a definition.
+     */
+    @Override
+    public void setAbstract()
+    {
+        super.setAbstract();
+
+        MetaTag abstractMetaTag = new MetaTag(this, IMetaAttributeConstants.ATTRIBUTE_ABSTRACT, new IMetaTagAttribute[0]);
+        addMetaTag(abstractMetaTag);
+    }
+
+    @Override
+    public boolean isPrivate()
+    {
+        if (super.isPrivate())
+        {
+            return true;
+        }
+        if (isConstructor())
+        {
+            IDefinition parent = getParent();
+            if (parent == null)
+            {
+                return false;
+            }
+            // if the construcutor does not have a private namespace, the parent
+            // class may have [RoyalePrivateConstructor] metadata instead. this
+            // is how private constructors are stored in bytecode.
+            IMetaTag[] metaTags = parent.getMetaTagsByName(IMetaAttributeConstants.ATTRIBUTE_PRIVATE_CONSTRUCTOR);
+            return metaTags != null && metaTags.length > 0;
+        }
+        return false;
+    }
+
+    @Override
     public boolean overridesAncestor(ICompilerProject project)
     {
         return (resolveOverriddenFunction(project) != null);
@@ -652,6 +700,12 @@
         	if (!definition.isPrivate()) return true;
             return findPrivates;
         }
+        
+        @Override
+        public boolean test(IDefinition input)
+        {
+            return apply(input);
+        }
     }
 
 }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/NamespaceDefinition.java b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/NamespaceDefinition.java
index fc1fd10..bbdef2e 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/NamespaceDefinition.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/NamespaceDefinition.java
@@ -46,7 +46,6 @@
 import org.apache.royale.compiler.definitions.IFunctionDefinition;
 import org.apache.royale.compiler.definitions.INamespaceDefinition;
 import org.apache.royale.compiler.definitions.IPackageDefinition;
-import org.apache.royale.compiler.definitions.references.INamespaceReference;
 import org.apache.royale.compiler.definitions.references.INamespaceResolvedReference;
 import org.apache.royale.compiler.filespecs.IFileSpecification;
 import org.apache.royale.compiler.internal.projects.CompilerProject;
@@ -1948,6 +1947,12 @@
                 }
                 return true;
             }
+            
+            @Override
+            public boolean test(IDefinition input)
+            {
+                return apply(input);
+            }
 
             /**
              * Determine if a reference from one definition to another should be considered a forward
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/VariableDefinition.java b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/VariableDefinition.java
index d0bd2cd..a465894 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/VariableDefinition.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/VariableDefinition.java
@@ -221,7 +221,8 @@
     	return initializer;
 	}
     
-    public void setInitializer(IExpressionNode initExpr)
+    @SuppressWarnings("incomplete-switch")
+	public void setInitializer(IExpressionNode initExpr)
     {
         if( initExpr != null )
         {
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/VectorInformation.java b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/VectorInformation.java
index d83b27a..1310790 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/VectorInformation.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/VectorInformation.java
@@ -198,14 +198,14 @@
         //add the fixed getter/setter pair
         GetterNode fixGetter = new GetterNode(null, null, new IdentifierNode("fixed"));
         NamespaceIdentifierNode pub = new NamespaceIdentifierNode(INamespaceConstants.public_);
-        pub.span(-1, -1, -1, -1);
+        pub.span(-1, -1, -1, -1, -1, -1);
         fixGetter.setNamespace(pub);
         fixGetter.setType(null, new IdentifierNode(IASLanguageConstants.Boolean));
         retVal[2] = fixGetter;
 
         SetterNode fixSetter = new SetterNode(null, null, new IdentifierNode("fixed"));
         pub = new NamespaceIdentifierNode(INamespaceConstants.public_);
-        pub.span(-1, -1, -1, -1);
+        pub.span(-1, -1, -1, -1, -1, -1);
         fixSetter.setNamespace(pub);
         fixSetter.setType(null, new IdentifierNode(IASLanguageConstants.void_));
         ParameterNode value = new ParameterNode(new IdentifierNode("value"));
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/references/ResolvedQualifiersReference.java b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/references/ResolvedQualifiersReference.java
index 1561d13..bf2ac97 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/references/ResolvedQualifiersReference.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/references/ResolvedQualifiersReference.java
@@ -128,7 +128,7 @@
             }
             default:
             {
-                IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs);
+                IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs, false);
                 if (d == null)
                     return AmbiguousDefinition.get();
                 return d;
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/embedding/EmbedData.java b/compiler/src/main/java/org/apache/royale/compiler/internal/embedding/EmbedData.java
index 404c693..544133c 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/embedding/EmbedData.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/embedding/EmbedData.java
@@ -47,7 +47,6 @@
 import org.apache.royale.compiler.internal.embedding.transcoders.SoundTranscoder;
 import org.apache.royale.compiler.internal.embedding.transcoders.TranscoderBase;
 import org.apache.royale.compiler.internal.embedding.transcoders.XMLTranscoder;
-import org.apache.royale.compiler.internal.projects.CompilerProject;
 import org.apache.royale.compiler.internal.projects.ASProject;
 import org.apache.royale.compiler.internal.projects.RoyaleProject;
 import org.apache.royale.compiler.internal.projects.SourcePathManager;
@@ -63,6 +62,7 @@
 import org.apache.royale.compiler.problems.EmbedUnrecogniedFileTypeProblem;
 import org.apache.royale.compiler.problems.FontEmbeddingNotSupported;
 import org.apache.royale.compiler.problems.ICompilerProblem;
+import org.apache.royale.compiler.projects.IASProject;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.units.ICompilationUnit;
 import org.apache.royale.swc.ISWCFileEntry;
@@ -143,6 +143,7 @@
     private ISWCFileEntry swcSource;
     @SuppressWarnings("unused")
     private SkinClassInfo skinClassInfo;
+    private ICompilerProject project;
 
     /**
      * Add an attribute
@@ -156,6 +157,7 @@
      */
     public boolean addAttribute(ICompilerProject project, ISourceLocation location, String key, String value, Collection<ICompilerProblem> problems)
     {
+    	this.project = project;
         boolean hadError = false;
         try
         {
@@ -346,6 +348,7 @@
             }
             else if (EmbedAttribute.ADV_ANTI_ALIASING.equals(key) ||
                     EmbedAttribute.EMBED_AS_CFF.equals(key) ||
+                    EmbedAttribute.UNICODE_RANGE.equals(key) ||
                     EmbedAttribute.FONT_FAMILY.equals(key) ||
                     EmbedAttribute.FONT_NAME.equals(key) ||
                     EmbedAttribute.FONT_STYLE.equals(key) ||
@@ -405,6 +408,18 @@
             problems.add(new EmbedNoSourceAttributeProblem(location));
             return false;
         }
+        String uniqueName = source;
+        List<File> sourcePaths = ((IASProject)project).getSourcePath();
+        for (File sourcePath : sourcePaths)
+        {
+        	String sourcePathString = sourcePath.getAbsolutePath();
+        	if (source.startsWith(sourcePathString))
+        	{
+        		uniqueName = source.substring(sourcePathString.length());
+        		uniqueName = uniqueName.replace("\\", "/");
+        		break;
+        	}
+        }
 
         // also check that we have a mimetype set, as don't know what transcoder
         // to create without it!
@@ -488,6 +503,8 @@
         if (transcoder == null)
             return false;
 
+        transcoder.hashCodeSourceName = uniqueName;
+        
         // there were problems with the transcoder because of attribute settings
         // so don't return it, and let the user deal with the errors
         if (!transcoder.analyze(location, problems))
@@ -518,10 +535,25 @@
             source = swcSource.getContainingSWCPath().concat(source);
         }
 
+        String uniqueName = source;
+        List<File> sourcePaths = ((IASProject)project).getSourcePath();
+        for (File sourcePath : sourcePaths)
+        {
+        	String sourcePathString = sourcePath.getAbsolutePath();
+        	if (source.startsWith(sourcePathString))
+        	{
+        		uniqueName = source.substring(sourcePathString.length());
+        		uniqueName = uniqueName.replace("\\", "/");
+        		break;
+        	}
+        }
         String filename = FilenameUtils.getName(source);
         filename = filename.replace(".", "_");
-        String qname = filename + "$" + StringEncoder.stringToMD5String(source);
-
+        String qname = filename + "$" + StringEncoder.stringToMD5String(uniqueName);
+        transcoder.hashCodeSourceName = uniqueName;
+//        System.out.println("Embed UniqueName: " + uniqueName);
+//        System.out.println("Embed QName: " + qname);
+        
         // add the transcoder hashCode to the end of the QName to ensure
         // two embed data's with the same source, but different attributes
         // don't clash
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/embedding/transcoders/MovieTranscoder.java b/compiler/src/main/java/org/apache/royale/compiler/internal/embedding/transcoders/MovieTranscoder.java
index 928d192..dde0e8f 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/embedding/transcoders/MovieTranscoder.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/embedding/transcoders/MovieTranscoder.java
@@ -27,7 +27,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.royale.compiler.caches.ISWFCache;
 import org.apache.royale.compiler.common.ISourceLocation;
 import org.apache.royale.compiler.constants.IASKeywordConstants;
 import org.apache.royale.compiler.constants.INamespaceConstants;
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/embedding/transcoders/TranscoderBase.java b/compiler/src/main/java/org/apache/royale/compiler/internal/embedding/transcoders/TranscoderBase.java
index caf7a81..60fa370 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/embedding/transcoders/TranscoderBase.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/embedding/transcoders/TranscoderBase.java
@@ -79,6 +79,7 @@
     protected String baseClassQName;
     protected String source;
     private EmbedMIMEType mimeType;
+    public String hashCodeSourceName;
 
     /**
      * Transcode the embedded asset
@@ -354,7 +355,7 @@
     public int hashCode()
     {
         int hashCode = 0;
-        hashCode = source.hashCode();
+        hashCode = hashCodeSourceName.hashCode();
         hashCode ^= baseClassQName.hashCode();
         hashCode ^= mimeType.toString().hashCode(); // the toString() gives us a reproducible hash code
 
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/filespecs/SWCFileSpecification.java b/compiler/src/main/java/org/apache/royale/compiler/internal/filespecs/SWCFileSpecification.java
index 3e4939f..10b78c9 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/filespecs/SWCFileSpecification.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/filespecs/SWCFileSpecification.java
@@ -139,4 +139,10 @@
 
         return new BufferedReader(new InputStreamReader(bufferedStrm, bom.charset));
     }
+
+	@Override
+	public void setLastModified(long fileDate) {
+		// TODO Auto-generated method stub
+		
+	}
 }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/filespecs/StringFileSpecification.java b/compiler/src/main/java/org/apache/royale/compiler/internal/filespecs/StringFileSpecification.java
index 243d2fe..01f2383 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/filespecs/StringFileSpecification.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/filespecs/StringFileSpecification.java
@@ -77,4 +77,10 @@
         return false;
     }
 
+	@Override
+	public void setLastModified(long fileDate) {
+		// TODO Auto-generated method stub
+		
+	}
+
 }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/filespecs/ZipFileSpecification.java b/compiler/src/main/java/org/apache/royale/compiler/internal/filespecs/ZipFileSpecification.java
index b9d4b5b..4bfd6ab 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/filespecs/ZipFileSpecification.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/filespecs/ZipFileSpecification.java
@@ -123,4 +123,10 @@
 	{
 		return false;
 	}
+
+	@Override
+	public void setLastModified(long fileDate) {
+		// TODO Auto-generated method stub
+		
+	}
 }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/mxml/MXMLTextData.java b/compiler/src/main/java/org/apache/royale/compiler/internal/mxml/MXMLTextData.java
index 0fa93d6..4e3c61f 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/mxml/MXMLTextData.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/mxml/MXMLTextData.java
@@ -293,7 +293,8 @@
     /**
      * @return The start offset of actual content
      */
-    public int getContentsStart()
+    @SuppressWarnings("incomplete-switch")
+	public int getContentsStart()
     {
         switch (type)
         {
@@ -313,7 +314,8 @@
     /**
      * @return The end offset of content
      */
-    public int getContentsEnd()
+    @SuppressWarnings("incomplete-switch")
+	public int getContentsEnd()
     {
         switch (type)
         {
@@ -335,7 +337,8 @@
         return getLine();
     }
 
-    public int getContentsColumn()
+    @SuppressWarnings("incomplete-switch")
+	public int getContentsColumn()
     {
         switch (type)
         {
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ASToken.java b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ASToken.java
index 52f2040..fa8b149 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ASToken.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ASToken.java
@@ -463,6 +463,7 @@
             case TOKEN_MODIFIER_NATIVE:
             case TOKEN_MODIFIER_OVERRIDE:
             case TOKEN_MODIFIER_STATIC:
+            case TOKEN_MODIFIER_ABSTRACT:
                 return true;
         }
         return false;
@@ -514,6 +515,7 @@
             case TOKEN_MODIFIER_OVERRIDE:
             case TOKEN_MODIFIER_STATIC:
             case TOKEN_MODIFIER_VIRTUAL:
+            case TOKEN_MODIFIER_ABSTRACT:
             case TOKEN_RESERVED_WORD_GET:
             case TOKEN_RESERVED_WORD_SET:
             case TOKEN_RESERVED_WORD_NAMESPACE:
@@ -655,6 +657,7 @@
             case TOKEN_MODIFIER_NATIVE:
             case TOKEN_MODIFIER_OVERRIDE:
             case TOKEN_MODIFIER_STATIC:
+            case TOKEN_MODIFIER_ABSTRACT:
                 return true;
         }
         return false;
@@ -918,6 +921,7 @@
             case TOKEN_MODIFIER_NATIVE:
             case TOKEN_MODIFIER_OVERRIDE:
             case TOKEN_MODIFIER_STATIC:
+            case TOKEN_MODIFIER_ABSTRACT:
                 return ASTokenKind.MODIFIER;
             case HIDDEN_TOKEN_BUILTIN_NS:
             case TOKEN_NAMESPACE_ANNOTATION:
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/BaseASParser.java b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/BaseASParser.java
index a8c3d7f..62bdaee 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/BaseASParser.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/BaseASParser.java
@@ -1520,7 +1520,18 @@
                     (NamespaceIdentifierNode)left,
                     (ASToken)op,
                     (IdentifierNode)right);
-            result = (ExpressionNodeBase) evaluateConstNodeExpression(cn);
+            IASNode possibleResult = evaluateConstNodeExpression(cn);
+            //it's possible for evaluateConstNodeExpression() to return null
+            //if that happens, fall back to the same behavior as the final
+            //else to avoid a null reference exception -JT
+            if (possibleResult != null)
+            {
+                result = (ExpressionNodeBase) possibleResult;
+            }
+            else
+            {
+                result = new NamespaceAccessExpressionNode(left, op, right);
+            }
         }
         else
         {
@@ -1562,7 +1573,7 @@
         }
         else
         {
-            block.span(blockToken.getStart() + 1, blockToken.getStart() + 1, blockToken.getLine(), blockToken.getColumn());
+            block.span(blockToken.getStart() + 1, blockToken.getStart() + 1, blockToken.getLine(), blockToken.getColumn(), blockToken.getLine(), blockToken.getColumn());
         }
     }
 
@@ -2329,7 +2340,7 @@
     }
 
     private static final ImmutableSet<String> CONTEXTUAL_RESERVED_KEYWORD_MODIFIERS =
-            ImmutableSet.of("dynamic", "final", "native", "static", "override");
+            ImmutableSet.of("dynamic", "final", "native", "static", "override", "abstract");
 
     /**
      * Recover from {@link CanNotInsertSemicolonProblem} after an expression
@@ -2854,6 +2865,7 @@
                 case TOKEN_MODIFIER_OVERRIDE:
                 case TOKEN_MODIFIER_STATIC:
                 case TOKEN_MODIFIER_VIRTUAL:
+                case TOKEN_MODIFIER_ABSTRACT:
                     return true;
             }
         }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ConfigProcessor.java b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ConfigProcessor.java
index 3d30c7d..89fcd51 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ConfigProcessor.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ConfigProcessor.java
@@ -52,7 +52,6 @@
 import org.apache.royale.compiler.internal.tree.as.NumericLiteralNode;
 import org.apache.royale.compiler.internal.tree.as.ScopedBlockNode;
 import org.apache.royale.compiler.internal.workspaces.Workspace;
-import org.apache.royale.compiler.parsing.IASToken;
 import org.apache.royale.compiler.problems.CannotResolveConfigExpressionProblem;
 import org.apache.royale.compiler.problems.CannotResolveProjectLevelConfigExpressionProblem;
 import org.apache.royale.compiler.problems.ConflictingNameInNamespaceProblem;
@@ -159,6 +158,24 @@
 			// TODO Auto-generated method stub
 			return false;
 		}
+
+		@Override
+		public boolean getAllowImportAliases() {
+			// TODO Auto-generated method stub
+			return false;
+		}
+
+		@Override
+		public boolean getAllowAbstractClasses() {
+			// TODO Auto-generated method stub
+			return false;
+		}
+
+        @Override
+        public boolean getAllowPrivateConstructors() {
+            // TODO Auto-generated method stub
+            return false;
+        }
     }
 
     /**
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/StreamingASTokenizer.java b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/StreamingASTokenizer.java
index 2cb8e99..32017a4 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/StreamingASTokenizer.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/StreamingASTokenizer.java
@@ -101,6 +101,7 @@
             .put(IASKeywordConstants.OVERRIDE, TOKEN_MODIFIER_OVERRIDE)
             .put(IASKeywordConstants.STATIC, TOKEN_MODIFIER_STATIC)
             .put(IASKeywordConstants.VIRTUAL, TOKEN_MODIFIER_VIRTUAL)
+            .put(IASKeywordConstants.ABSTRACT, TOKEN_MODIFIER_ABSTRACT)
             .put(IASKeywordConstants.SET, TOKEN_RESERVED_WORD_SET)
             // Keywords with special token types that affect subsequent blocks
             .put(IASKeywordConstants.CATCH, TOKEN_KEYWORD_CATCH)
@@ -917,6 +918,7 @@
                 case TOKEN_MODIFIER_OVERRIDE:
                 case TOKEN_MODIFIER_STATIC:
                 case TOKEN_MODIFIER_VIRTUAL:
+                case TOKEN_MODIFIER_ABSTRACT:
                 {
                     // previous token is either a modifier or a namespace, or if
                     // null, assume keyword
@@ -938,6 +940,7 @@
                             case TOKEN_MODIFIER_OVERRIDE:
                             case TOKEN_MODIFIER_STATIC:
                             case TOKEN_MODIFIER_VIRTUAL:
+                            case TOKEN_MODIFIER_ABSTRACT:
                             case TOKEN_NAMESPACE_ANNOTATION:
                             case TOKEN_NAMESPACE_NAME:
                             case HIDDEN_TOKEN_BUILTIN_NS:
@@ -1773,6 +1776,7 @@
                 case TOKEN_MODIFIER_OVERRIDE:
                 case TOKEN_MODIFIER_STATIC:
                 case TOKEN_MODIFIER_VIRTUAL:
+                case TOKEN_MODIFIER_ABSTRACT:
                 case TOKEN_KEYWORD_CLASS:
                 case TOKEN_KEYWORD_INTERFACE:
                 case TOKEN_NAMESPACE_ANNOTATION:
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/ASCProject.java b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/ASCProject.java
index f6b78fa..f542cf3 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/ASCProject.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/ASCProject.java
@@ -80,4 +80,22 @@
 		// TODO Auto-generated method stub
 		return false;
 	}
+
+	@Override
+	public boolean getAllowImportAliases() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public boolean getAllowAbstractClasses() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public boolean getAllowPrivateConstructors() {
+		// TODO Auto-generated method stub
+		return false;
+	}
 }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/CompilerProject.java b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/CompilerProject.java
index 88b42e6..397bb6b 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/CompilerProject.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/CompilerProject.java
@@ -847,7 +847,8 @@
         return fatalProblems == null ? Collections.<ICompilerProblem>emptyList() : fatalProblems;
     }
 
-    @Override
+    @SuppressWarnings("incomplete-switch")
+	@Override
     public ITypeDefinition getBuiltinType(IASLanguageConstants.BuiltinType type)
     {
         switch( type )
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/DependencyGraph.java b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/DependencyGraph.java
index a7fa031..86ae45b 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/DependencyGraph.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/DependencyGraph.java
@@ -33,6 +33,7 @@
 
 import org.apache.royale.compiler.common.DependencyType;
 import org.apache.royale.compiler.common.DependencyTypeSet;
+import org.apache.royale.compiler.config.CompilerDiagnosticsConstants;
 import org.apache.royale.compiler.exceptions.CircularDependencyException;
 import org.apache.royale.compiler.internal.graph.Graph;
 import org.apache.royale.compiler.internal.graph.GraphEdge;
@@ -43,6 +44,7 @@
 import org.apache.royale.compiler.units.ICompilationUnit;
 import com.google.common.base.Function;
 import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
 
 /**
  * Class to track dependencies in a {@link CompilerProject}.
@@ -498,6 +500,8 @@
             }
         });
     }
+    
+    public CircularDependencyException lastCircularDependencyException;
 
     /**
      * Computes the list of all {@link ICompilationUnit}'s that the specified
@@ -520,6 +524,7 @@
         lock.readLock().lock();
         try
         {
+        	lastCircularDependencyException = null;
             final ArrayList<ICompilationUnit> sortedList = new ArrayList<ICompilationUnit>(graph.getVertices().size());
             TopologicalSort.IVisitor<ICompilationUnit, Edge> visitor =
                     new TopologicalSort.IVisitor<ICompilationUnit, Edge>()
@@ -549,6 +554,23 @@
             }
             catch (CircularDependencyException e1)
             {
+    			if ((CompilerDiagnosticsConstants.diagnostics & CompilerDiagnosticsConstants.GOOG_DEPS) == CompilerDiagnosticsConstants.GOOG_DEPS)
+    			{
+    				System.out.println("Circular Dependency Found");
+    				@SuppressWarnings("unchecked")
+					ImmutableList<ICompilationUnit> nodes = (ImmutableList<ICompilationUnit>) e1.getCircularDependency();
+    				for (ICompilationUnit node : nodes)
+    				{
+    					try {
+							System.out.println(node.getQualifiedNames().toString());
+						} catch (InterruptedException e2) {
+							// TODO Auto-generated catch block
+							e2.printStackTrace();
+						}
+    				}
+    				System.out.println("End of Circular Dependency");
+    			}
+    			lastCircularDependencyException = e1;
                 assert false : "CircularDependencyException";
             }
             return sortedList;
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/LibraryPathManager.java b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/LibraryPathManager.java
index c9e7550..17ef23d 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/LibraryPathManager.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/LibraryPathManager.java
@@ -470,7 +470,8 @@
      * @param swcFilesToRemove SWC file paths
      * @return compilation units associated with the SWC files
      */
-    private List<ICompilationUnit> computeUnitsToRemove(final Collection<String> swcFilesToRemove)
+    @SuppressWarnings("incomplete-switch")
+	private List<ICompilationUnit> computeUnitsToRemove(final Collection<String> swcFilesToRemove)
     {
         final List<ICompilationUnit> unitsToRemove;
         unitsToRemove = new ArrayList<ICompilationUnit>();
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProject.java b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProject.java
index e787d6c..e2a63e5 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProject.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProject.java
@@ -380,6 +380,7 @@
     private String objectProxyClass;
     private String xmlWatcherClass;
     private Name xmlWatcherClassName;
+    private String swfDebugfileAlias;
     
     /**
      * The fully-qualified name of the runtime class
@@ -2348,27 +2349,50 @@
 		{
 			if (meta.getTagName().equals(IMetaAttributeConstants.ATTRIBUTE_SWFOVERRIDE))
 			{
-				IMetaTagAttribute attr = meta.getAttribute(IMetaAttributeConstants.NAME_SWFOVERRIDE_ALTPARAMS);
-				if (attr != null)
+				IMetaTagAttribute altattr = meta.getAttribute(IMetaAttributeConstants.NAME_SWFOVERRIDE_ALTPARAMS);
+				if (altattr != null)
 				{
-					// format is expectedQName:allowedQName,expectedQName:allowedQName.
-					// we don't know which parameter it is so we're assuming for now that any mapping
-					// applies to all occurences of that type in the parameter list
-					String paramList = attr.getValue();
-					String[] paramMap;
-					if (paramList.contains(","))
-						paramMap = paramList.split(",");
+					String altparamList = altattr.getValue();
+					String[] altparamMap;
+					if (altparamList.contains(","))
+						altparamMap = altparamList.split(",");
 					else
 					{
-						paramMap = new String[1];
-						paramMap[0] = paramList;
+						altparamMap = new String[1];
+						altparamMap[0] = altparamList;
 					}
-					for (String item : paramMap)
+					IMetaTagAttribute attr = meta.getAttribute(IMetaAttributeConstants.NAME_SWFOVERRIDE_PARAMS);
+					if (attr != null)
 					{
-						String[] parts = item.split(":");
-						if (expectedDefinition.getQualifiedName().equals(parts[0]))
-							if (((ITypeDefinition)actualDefinition).isInstanceOf(parts[1], this))
-								return true;
+						String paramList = attr.getValue();
+						String[] paramMap;
+						if (paramList.contains(","))
+							paramMap = paramList.split(",");
+						else
+						{
+							paramMap = new String[1];
+							paramMap[0] = paramList;
+						}
+						int n = paramMap.length;
+						for (int i = 0; i < n; i++)
+						{
+							String item = paramMap[i];
+							if (((ITypeDefinition)expectedDefinition).isInstanceOf(item, this))
+							{
+								String alts = altparamMap[i];
+								String[] altList;
+								if (alts.contains(":"))
+									altList = alts.split(":");
+								else
+								{
+									altList = new String[1];
+									altList[0] = alts;
+								}
+								for (String alt : altList)
+									if (((ITypeDefinition)actualDefinition).isInstanceOf(alt, this))
+										return true;
+							}
+						}
 					}
 				}
 			}
@@ -2430,6 +2454,51 @@
     	allowPrivateNameConflicts = allow;
     }
 
+    private boolean allowImportAliases = false;
+    
+    /**
+     * Indicates if import aliases are allowed.
+     */
+    @Override
+    public boolean getAllowImportAliases()
+    {
+    	return allowImportAliases;
+    }
+    public void setAllowImportAliases(boolean allow)
+    {
+    	allowImportAliases = allow;
+    }
+
+    private boolean allowAbstractClasses = false;
+    
+    /**
+     * Indicates if abstract classes are allowed.
+     */
+    @Override
+    public boolean getAllowAbstractClasses()
+    {
+    	return allowAbstractClasses;
+    }
+    public void setAllowAbstractClasses(boolean allow)
+    {
+    	allowAbstractClasses = allow;
+    }
+
+    private boolean allowPrivateConstructors = false;
+    
+    /**
+     * Indicates if private constructors are allowed.
+     */
+    @Override
+    public boolean getAllowPrivateConstructors()
+    {
+    	return allowPrivateConstructors;
+    }
+    public void setAllowPrivateConstructors(boolean allow)
+    {
+    	allowPrivateConstructors = allow;
+    }
+
 	@Override
 	public boolean isPlatformRule(ICSSRule rule) {
 		return true;
@@ -2520,4 +2589,19 @@
         return false;
 	}
 
+	@Override
+	public File getLinkReport(Configuration config) {
+		return config.getLinkReport();
+	}
+
+    public String getSwfDebugfileAlias()
+    {
+        return swfDebugfileAlias;
+    }
+    
+    public void setSwfDebugfileAlias(String swfDebugfileAlias)
+    {
+        this.swfDebugfileAlias = swfDebugfileAlias;
+    }
+
 }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProjectConfigurator.java b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProjectConfigurator.java
index df8d4fa..ef8c367 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProjectConfigurator.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProjectConfigurator.java
@@ -30,6 +30,7 @@
 import org.apache.royale.abc.semantics.Nsset;
 import org.apache.royale.compiler.config.Configuration;
 import org.apache.royale.compiler.config.Configurator;
+import org.apache.royale.compiler.filespecs.FileSpecification;
 import org.apache.royale.compiler.fxg.flex.FlexFXG2SWFTranscoder;
 import org.apache.royale.compiler.internal.as.codegen.BindableHelper;
 import org.apache.royale.compiler.internal.config.RoyaleTargetSettings;
@@ -262,7 +263,14 @@
 
             project.setStrictXML(configuration.isStrictXML());
             project.setAllowPrivateNameConflicts(configuration.getCompilerAllowPrivateNameConflicts());
+
+            project.setAllowImportAliases(configuration.getCompilerAllowImportAliases());
+            project.setAllowAbstractClasses(configuration.getCompilerAllowAbstractClasses());
+            project.setAllowPrivateConstructors(configuration.getCompilerAllowPrivateConstructors());
             
+            project.setSwfDebugfileAlias(configuration.getSwfDebugfileAlias());
+            if (configuration.getSwfDebugfileAlias() != null)
+            	FileSpecification.useCRLFFilter = true;
             DataTranscoder.embedClassName = configuration.getByteArrayEmbedClass();
         }
     }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/SourcePathManager.java b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/SourcePathManager.java
index 366cab1..da6b74f 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/SourcePathManager.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/SourcePathManager.java
@@ -256,7 +256,13 @@
                         {
                             DefinitionPriority defPriority = (DefinitionPriority)cu.getDefinitionPriority();
                             return defPriority.getBasePriority() == DefinitionPriority.BasePriority.SOURCE_PATH;
-                        }});
+                        }
+                        @Override
+                        public boolean test(ICompilationUnit input)
+                        {
+                            return apply(input);
+                        }
+                        });
                 unitsToRemove.addAll(sourcePathCompilationUnitsToRemove);
             }
         }
@@ -335,6 +341,11 @@
                         DefinitionPriority priority = ((DefinitionPriority)compilationUnit.getDefinitionPriority());
                         return priority.getBasePriority() == DefinitionPriority.BasePriority.SOURCE_PATH;
                     }
+                    @Override
+                    public boolean test(ICompilationUnit input)
+                    {
+                        return apply(input);
+                    }
                 });
     }
     
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScope.java b/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScope.java
index 434a2d9..b229304 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScope.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScope.java
@@ -1425,7 +1425,7 @@
         assert baseName.indexOf('.') == -1 : "baseName must not be any sort of qname";
         CompilerProject compilerProject = (CompilerProject)project;
         ASScopeCache scopeCache = compilerProject.getCacheForScope(this);
-        return filterWith(scopeCache.findProperty(baseName, dt), canEscapeWith);
+        return filterWith(scopeCache.findProperty(baseName, dt, canEscapeWith), canEscapeWith);
     }
 
     /**
@@ -1487,7 +1487,7 @@
                 assert def.isInProject(project);
                 break;
             default:
-                IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs);
+                IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs, false);
                 if (d != null)
                     def = d;
                 else
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScopeCache.java b/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScopeCache.java
index fb43722..d3dff76 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScopeCache.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScopeCache.java
@@ -25,6 +25,7 @@
 import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.definitions.IInterfaceDefinition;
 import org.apache.royale.compiler.definitions.INamespaceDefinition;
+import org.apache.royale.compiler.definitions.ITypeDefinition;
 import org.apache.royale.compiler.definitions.references.IResolvedQualifiersReference;
 import org.apache.royale.compiler.internal.definitions.AmbiguousDefinition;
 import org.apache.royale.compiler.internal.definitions.ClassDefinitionBase;
@@ -32,6 +33,7 @@
 import org.apache.royale.compiler.internal.definitions.TypeDefinitionBase;
 import org.apache.royale.compiler.internal.projects.CompilerProject;
 import org.apache.royale.compiler.projects.ICompilerProject;
+import org.apache.royale.compiler.units.ICompilationUnit;
 
 import com.google.common.collect.MapMaker;
 
@@ -131,15 +133,27 @@
      * @param dt Which type of dependency to introduce when we do the lookup
      * @return The IDefinition for the property, or null if it wasn't found
      */
-    IDefinition findProperty(String name, DependencyType dt)
+    IDefinition findProperty(String name, DependencyType dt, boolean favorTypes)
     {
         ConcurrentMap<String, IDefinition> map = getScopeChainMap();
 
         IDefinition result = map.get(name);
         if (result != null)
         {
-            assert result.isInProject(project);
             // We found a cached result - we're done
+        	// after making sure it has a dependency
+        	if (result instanceof ITypeDefinition)
+        	{
+	        	ICompilationUnit from = scope.getFileScope().getCompilationUnit();
+	            assert result.isInProject(project);
+	            
+	            String qname = result.getQualifiedName();
+	            ICompilationUnit to = ((ASProjectScope)project.getScope()).getCompilationUnitForDefinition(result);
+	            if (to == null && !(qname.contentEquals("void") || qname.contentEquals("*")))
+	            	System.out.println("No compilation unit for " + qname);	
+	            if (to != null)
+	            	project.addDependency(from, to, dt, qname);
+        	}
             return result;
         }
 
@@ -148,6 +162,7 @@
         // the benefit is that we avoid any sort of locking, which was proving expensive (time wise,
         // and memory wise).
 
+        boolean wasAmbiguous = false;
         IDefinition def = null;
         Set<INamespaceDefinition> namespaceSet = scope.getNamespaceSetForName(project, name);
         // Look for the definition in the scope
@@ -164,7 +179,8 @@
                 assert def.isInProject(project);
                 break;
             default:
-                IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs);
+            	wasAmbiguous = true;
+                IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs, favorTypes);
                 if (d != null)
                     def = d;
                 else {
@@ -186,7 +202,7 @@
             // If the dependency type is null we can't cache the name
             // resolution result, because the name resolution cache will not
             // be properly invalidated when the file containing the definition changes.
-            if (dt != null)
+            if (dt != null && !wasAmbiguous)
             {
                 result = map.putIfAbsent(name, def);
                 if (result == null)
@@ -294,7 +310,7 @@
                 break;
 
             default:
-                IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs);
+                IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs, false);
                 if (d != null)
                     def = d;
                 else
@@ -361,7 +377,7 @@
                 assert def.isInProject(project);
                 break;
             default:
-                IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs);
+                IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs, false);
                 if (d != null)
                     def = d;
                 else
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/NamespaceSetPredicate.java b/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/NamespaceSetPredicate.java
index c2684eb..44e775a 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/NamespaceSetPredicate.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/NamespaceSetPredicate.java
@@ -88,6 +88,12 @@
         return false;
     }
 
+    @Override
+    public boolean test(IDefinition input)
+    {
+        return apply(input);
+    }
+
     /**
      * Does the underlying namespace set contain the namespace passed in
      * @param d the namespace to check
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/TypeScope.java b/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/TypeScope.java
index 07ff53d..2a2a40b 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/TypeScope.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/TypeScope.java
@@ -662,5 +662,11 @@
         {
             return findStatics == definition.isStatic();
         }
+        
+        @Override
+        public boolean test(IDefinition input)
+        {
+            return apply(input);
+        }
     }
 }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/MethodBodySemanticChecker.java b/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/MethodBodySemanticChecker.java
index 6663afc..c455528 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/MethodBodySemanticChecker.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/MethodBodySemanticChecker.java
@@ -70,6 +70,8 @@
 import org.apache.royale.compiler.internal.definitions.VariableDefinition;
 import org.apache.royale.compiler.problems.*;
 import org.apache.royale.compiler.projects.ICompilerProject;
+import org.apache.royale.compiler.scopes.IASScope;
+import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IASNode;
 import org.apache.royale.compiler.tree.as.IBinaryOperatorNode;
 import org.apache.royale.compiler.tree.as.ICompoundAssignmentNode;
@@ -84,6 +86,8 @@
 import org.apache.royale.compiler.tree.as.INumericLiteralNode;
 import org.apache.royale.compiler.tree.as.IParameterNode;
 import org.apache.royale.compiler.tree.as.IReturnNode;
+import org.apache.royale.compiler.tree.as.IScopedNode;
+import org.apache.royale.compiler.tree.as.ITypedExpressionNode;
 import org.apache.royale.compiler.tree.as.IUnaryOperatorNode;
 import org.apache.royale.compiler.tree.as.IVariableNode;
 import org.apache.royale.compiler.internal.as.codegen.ABCGeneratingReducer;
@@ -390,18 +394,18 @@
 
         if (!SemanticUtils.isValidTypeConversion(expected_type, actual_type, project, currentScope.getInInvisibleCompilationUnit()))
         {
-            addProblem(new ImplicitTypeCheckCoercionToUnrelatedTypeProblem(iNode, actual_type.getBaseName(), expected_type.getBaseName()));
+            addProblem(new ImplicitTypeCheckCoercionToUnrelatedTypeProblem(iNode, actual_type.getQualifiedName(), expected_type.getQualifiedName()));
         }
         else
         {
             SpecialValue value = getSpecialValue((IExpressionNode)iNode);
             if (value == SpecialValue.UNDEFINED) // test for undefined
             {
-                addProblem(new ImplicitTypeCheckCoercionToUnrelatedTypeProblem(iNode, IASLanguageConstants.UNDEFINED, expected_type.getBaseName()));                
+                addProblem(new ImplicitTypeCheckCoercionToUnrelatedTypeProblem(iNode, IASLanguageConstants.UNDEFINED, expected_type.getQualifiedName()));                
             }
             else if (iNode instanceof LiteralNode && IASKeywordConstants.NULL.equals(((LiteralNode)iNode).getValue())) // test for null
             {
-                addProblem(new ImplicitTypeCheckCoercionToUnrelatedTypeProblem(iNode, IASKeywordConstants.NULL, expected_type.getBaseName()));
+                addProblem(new ImplicitTypeCheckCoercionToUnrelatedTypeProblem(iNode, IASKeywordConstants.NULL, expected_type.getQualifiedName()));
             }
         }
     }
@@ -570,11 +574,11 @@
             {
                 if ( utils.isInstanceOf(expected_type, actual_type) )
                 {
-                    addProblem(new ImplicitCoercionToSubtypeProblem(iNode, actual_type.getBaseName(), expected_type.getBaseName()));
+                    addProblem(new ImplicitCoercionToSubtypeProblem(iNode, actual_type.getQualifiedName(), expected_type.getQualifiedName()));
                 }
                 else
                 {
-                    addProblem(new ImplicitCoercionToUnrelatedTypeProblem(iNode, actual_type.getBaseName(), expected_type.getBaseName()));
+                    addProblem(new ImplicitCoercionToUnrelatedTypeProblem(iNode, actual_type.getQualifiedName(), expected_type.getQualifiedName()));
                 }
             }
         }
@@ -785,9 +789,26 @@
         {
             FunctionNode func = (FunctionNode)iNode;
 
+            if (SemanticUtils.isFunctionClosure(func))
+            {
+                for (IASNode thisNode : findThisIdentifierNodes(func))
+                {
+                    addProblem(new ThisUsedInClosureProblem(thisNode));
+                }
+            }
+
             IDefinition def = func.getDefinition();
 
-            if ( !( def.hasModifier(ASModifier.NATIVE ) || def.hasModifier(ASModifier.DYNAMIC) || func.isConstructor() ) )
+            if ( project.getAllowAbstractClasses()
+                    && def.isAbstract()
+                    && SemanticUtils.canBeAbstract(iNode, currentScope.getProject()))
+            {
+                if ( func.hasBody() )
+                {
+                    addProblem(new AbstractMethodWithBodyProblem(SemanticUtils.getFunctionProblemNode(func)));
+                }
+            }
+            else if ( !( def.hasModifier(ASModifier.NATIVE ) || def.hasModifier(ASModifier.DYNAMIC) || func.isConstructor() ) )
             {
                 if ( !func.hasBody() )
                 {
@@ -797,6 +818,24 @@
         }
     }
 
+    private static List<IASNode> findThisIdentifierNodes(IASNode iNode)
+    {
+        List<IASNode> result = new ArrayList<IASNode>();
+        for(int i = 0, count = iNode.getChildCount(); i < count; i++)
+        {
+            IASNode child = iNode.getChild(i);
+            if(SemanticUtils.isThisKeyword(child))
+            {
+                result.add(child);
+            }
+            else if(!child.isTerminal() && !(child instanceof IFunctionNode))
+            {
+                result.addAll(findThisIdentifierNodes(child));
+            }
+        }
+        return result;
+    }
+
     public void checkNativeMethod(IASNode iNode)
     {
         if( iNode instanceof FunctionNode )
@@ -941,6 +980,7 @@
     public void checkFunctionDefinition(IFunctionNode iNode, FunctionDefinition def )
     {
         SemanticUtils.checkReturnValueHasNoTypeDeclaration(this.currentScope, iNode, def);
+        SemanticUtils.checkParametersHaveNoTypeDeclaration(this.currentScope, iNode, def);
         
         if (SemanticUtils.isInFunction(iNode))
         {
@@ -1793,6 +1833,21 @@
             IExpressionNode site = ((IMemberAccessExpressionNode)nameNode).getRightOperandNode();
             def = ((IFunctionCallNode)iNode).resolveCalledExpression(project);
             checkDeprecated(site, def);
+            if (def == null || def.isAbstract())
+            {
+            	String methodName = null;
+            	if (nameNode.getNodeID() == ASTNodeID.MemberAccessExpressionID)
+            	{
+            		MemberAccessExpressionNode mae = (MemberAccessExpressionNode)nameNode;
+            		IExpressionNode rightNode = mae.getRightOperandNode();
+            		if (rightNode.getNodeID() == ASTNodeID.IdentifierID)
+            			methodName = ((IdentifierNode)rightNode).getName();
+            	}
+                assert methodName != null;
+                addProblem(new CallUndefinedMethodProblem( 
+                        iNode, methodName
+                    ));
+            }
         }
 
         if ( this.superState == SuperState.Initial )
@@ -1985,7 +2040,8 @@
      * 
      * @param call_node {@link FunctionCallNode} that has the "new" call.
      */
-    public void checkNewExpr(IASNode call_node)
+    @SuppressWarnings("incomplete-switch")
+	public void checkNewExpr(IASNode call_node)
     {
         final ExpressionNodeBase name = ((FunctionCallNode)call_node).getNameNode();
         if (name instanceof MemberAccessExpressionNode)
@@ -1998,7 +2054,8 @@
             }
             else if ( def instanceof ClassDefinition )
             {
-                // pass
+                IClassDefinition classDef = (IClassDefinition) def;
+                checkPrivateConstructorNewExpr(call_node, null, classDef, classDef.getConstructor());
             }
             else if ( def instanceof GetterDefinition )
             {
@@ -2014,6 +2071,16 @@
                         addProblem(new MethodCannotBeConstructorProblem(call_node));
                         break;
                 }
+
+                if (func_def.isConstructor())
+                {
+                    IDefinition class_def = func_def.getParent();
+                    checkPrivateConstructorNewExpr(call_node, null, class_def, func_def);
+                }
+            }
+            else if (def == null)
+            {
+            	addProblem(new UnresolvedClassReferenceProblem(call_node, func_name.getDisplayString()));
             }
         }
     }
@@ -2025,11 +2092,7 @@
     {
         IDefinition def = class_binding.getDefinition();
 
-        if ( class_binding.isLocal() )
-        {
-            //  No checking required.
-        }
-        else if ( def == null && utils.definitionCanBeAnalyzed(class_binding) && !(class_binding.getName().isTypeName()) )
+        if ( def == null && utils.definitionCanBeAnalyzed(class_binding) && !(class_binding.getName().isTypeName()) )
         {
             // Note: don't have to check accessability because
             // AS3 mandates constructors be public.
@@ -2049,12 +2112,21 @@
         {
             ClassDefinition class_def = (ClassDefinition)def;
 
+            if ( project.getAllowAbstractClasses() && class_def.isAbstract() )
+            {
+                addProblem(new AbstractClassCannotBeInstantiatedProblem(
+                    roundUpUsualSuspects(class_binding, iNode)
+                ));
+            }
+
             IFunctionDefinition ctor = class_def.getConstructor();
 
             if ( ctor instanceof FunctionDefinition )
             {
-                FunctionDefinition func = (FunctionDefinition)ctor;
-                checkFormalsVsActuals(iNode, func, args);
+                FunctionDefinition func_def = (FunctionDefinition)ctor;
+                checkFormalsVsActuals(iNode, func_def, args);
+                
+                checkPrivateConstructorNewExpr(iNode, class_binding, class_def, func_def);
             }
         }
         else if ( def instanceof GetterDefinition )
@@ -2066,17 +2138,85 @@
 
             IFunctionDefinition.FunctionClassification func_type = func_def.getFunctionClassification();
 
-            if ( func_type.equals(IFunctionDefinition.FunctionClassification.CLASS_MEMBER) || func_type.equals(IFunctionDefinition.FunctionClassification.INTERFACE_MEMBER) )
+            if (func_def.isConstructor())
+            {
+                IDefinition class_def = func_def.getParent();
+                checkPrivateConstructorNewExpr(iNode, class_binding, class_def, func_def);
+            }
+            else if ( func_type.equals(IFunctionDefinition.FunctionClassification.CLASS_MEMBER) || func_type.equals(IFunctionDefinition.FunctionClassification.INTERFACE_MEMBER) )
             {
                 addProblem(new MethodCannotBeConstructorProblem(
                     roundUpUsualSuspects(class_binding, iNode)
                 ));
             }
         }
+        else if ( def instanceof IVariableDefinition)
+        {
+            if (class_binding.isLocal())
+            {
+                // Note: previously, local variable bindings were not checked at
+                // all, but actually, variables of most types cannot be used with a
+                // "new" expression -JT
+
+                ITypeDefinition typeDef = def.resolveType(project);
+                if (typeDef != null
+                        && !SemanticUtils.isBuiltin(typeDef, BuiltinType.CLASS, project)
+                        && !SemanticUtils.isBuiltin(typeDef, BuiltinType.FUNCTION, project)
+                        && !SemanticUtils.isBuiltin(typeDef, BuiltinType.OBJECT, project)
+                        && !SemanticUtils.isBuiltin(typeDef, BuiltinType.ANY_TYPE, project))
+                {
+                    addProblem(new CallUndefinedMethodProblem(
+                        roundUpUsualSuspects(class_binding, iNode),
+                        class_binding.getName().getBaseName()
+                    ));
+                }
+            }
+        }
 
         checkReference(class_binding);
     }
 
+    private void checkPrivateConstructorNewExpr(IASNode iNode, Binding class_binding, IDefinition classDef, IFunctionDefinition funcDef)
+    {
+        if (!project.getAllowPrivateConstructors() || !funcDef.isPrivate())
+        {
+            return;
+        }
+
+        IScopedNode enclosingScope = iNode.getContainingScope();
+        
+        if (enclosingScope != null)
+        {
+            boolean needsProblem = true;
+            IASScope currentScope = enclosingScope.getScope();
+            while (currentScope != null)
+            {
+                IDefinition currentDef = currentScope.getDefinition();
+                if (currentDef instanceof IClassDefinition)
+                {
+                    needsProblem = !classDef.equals(currentScope.getDefinition());
+                    break;
+                }
+                currentScope = currentScope.getContainingScope();
+            }
+            if(needsProblem)
+            {
+                if(class_binding != null)
+                {
+                    addProblem(new InaccessibleConstructorReferenceProblem(
+                        roundUpUsualSuspects(class_binding, iNode), classDef.getQualifiedName()
+                    ));
+                }
+                else
+                {
+                    addProblem(new InaccessibleConstructorReferenceProblem(
+                        iNode, classDef.getQualifiedName()
+                    ));
+                }
+            }
+        }
+    }
+
     /**
      *  Check a return expression that returns a value.
      *  @param iNode - the return statement.  
@@ -2143,7 +2283,7 @@
     {
         if ( SemanticUtils.isInFunction(iNode) )
         {
-            if ( SemanticUtils.functionMustReturnValue(iNode, this.project) )
+            if ( SemanticUtils.functionMustReturnValue(iNode, currentScope.getProject().getAllowAbstractClasses(), this.project) )
                 addProblem(new ReturnMustReturnValueProblem(iNode));
         }
         else if ( isInClassDefinition(iNode) )
@@ -2182,7 +2322,9 @@
         if  ( 
                 il.size() > 0 &&
                 il.lastElement() == ABCGeneratingReducer.synthesizedReturnVoid && 
-                SemanticUtils.functionMustReturnValue(iNode, this.project)
+                SemanticUtils.functionMustReturnValue(iNode,
+                    currentScope.getProject().getAllowAbstractClasses(),
+                    this.project)
             )
         {
             for ( IBasicBlock b: mbi.getCfg().blocksInControlFlowOrder() )
@@ -2219,6 +2361,13 @@
     {
         IASNode site = importNode.getImportNameNode();
         
+        String importAlias = importNode.getImportAlias();
+        if (importAlias != null && !project.getAllowImportAliases())
+        {
+            //import aliases need to be enabled
+            addProblem(new SyntaxProblem(importNode, "="));
+        }
+        
         if (!SemanticUtils.isValidImport(importNode, project, currentScope.getInInvisibleCompilationUnit()))
         {
             String importName = importNode.getImportName();
@@ -2409,6 +2558,13 @@
                 {
                     currentScope.addProblem(new StaticOutsideClassProblem(site));
                 }
+                else if( modifier == ASModifier.ABSTRACT )
+                {
+                    if(currentScope.getProject().getAllowAbstractClasses())
+                    {
+                        currentScope.addProblem(new AbstractOutsideClassProblem(site));
+                    }
+                }
             }
         }
 
@@ -2436,6 +2592,22 @@
             }
         }
 
+        ExpressionNodeBase typeNode = var.getTypeNode();
+        IExpressionNode currentTypeNode = typeNode;
+        IDefinition vectorType = project.getBuiltinType(IASLanguageConstants.BuiltinType.VECTOR);
+        while (currentTypeNode instanceof ITypedExpressionNode)
+        {
+            ITypedExpressionNode typedNode = (ITypedExpressionNode) currentTypeNode;
+            IExpressionNode collectionNode = typedNode.getCollectionNode();
+            IDefinition collectionType = collectionNode.resolve(project);
+            if (!vectorType.equals(collectionType))
+            {
+                currentScope.addProblem(new TypeParametersWithNonParameterizedTypeProblem(collectionNode));
+            }
+            //keep checking while there are nested types
+            currentTypeNode = typedNode.getTypeNode();
+        }
+
         // check if thise is an assignment in this declaration.
         // If so, do checks on that
         final ExpressionNodeBase rightNode = var.getAssignedValueNode();
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/SemanticUtils.java b/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/SemanticUtils.java
index 344f14f..d22d291 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/SemanticUtils.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/SemanticUtils.java
@@ -104,6 +104,7 @@
 import org.apache.royale.compiler.problems.DeprecatedAPIWithSinceAndReplacementProblem;
 import org.apache.royale.compiler.problems.DeprecatedAPIWithSinceProblem;
 import org.apache.royale.compiler.problems.ICompilerProblem;
+import org.apache.royale.compiler.problems.ParameterHasNoTypeDeclarationProblem;
 import org.apache.royale.compiler.problems.ReturnValueHasNoTypeDeclarationProblem;
 import org.apache.royale.compiler.problems.ScopedToDefaultNamespaceProblem;
 import org.apache.royale.compiler.problems.UnknownSuperclassProblem;
@@ -117,15 +118,18 @@
 import org.apache.royale.compiler.tree.as.IDefinitionNode;
 import org.apache.royale.compiler.tree.as.IExpressionNode;
 import org.apache.royale.compiler.tree.as.IFileNode;
+import org.apache.royale.compiler.tree.as.IFunctionCallNode;
 import org.apache.royale.compiler.tree.as.IFunctionNode;
 import org.apache.royale.compiler.tree.as.IIdentifierNode;
 import org.apache.royale.compiler.tree.as.IImportNode;
 import org.apache.royale.compiler.tree.as.ILanguageIdentifierNode;
 import org.apache.royale.compiler.tree.as.ILanguageIdentifierNode.LanguageIdentifierKind;
 import org.apache.royale.compiler.tree.as.ILiteralNode;
+import org.apache.royale.compiler.tree.as.IMemberAccessExpressionNode;
 import org.apache.royale.compiler.tree.as.INamespaceDecorationNode;
 import org.apache.royale.compiler.tree.as.INumericLiteralNode;
 import org.apache.royale.compiler.tree.as.IParameterNode;
+import org.apache.royale.compiler.tree.as.IScopedNode;
 import org.apache.royale.compiler.tree.as.ITryNode;
 import org.apache.royale.compiler.tree.as.IVariableNode;
 import org.apache.royale.compiler.tree.mxml.IMXMLEventSpecifierNode;
@@ -835,7 +839,7 @@
         if (base != null && base.isDynamicExpression(project))
         	return true;
         // the JS version of XML is not currently dynamic so special case it here.
-        if (base != null && base.getNodeID() == ASTNodeID.IdentifierID && IdentifierNode.isXMLish(base.resolveType(project), project))
+        if (base != null && base.getNodeID() == ASTNodeID.IdentifierID && isXMLish(base.resolveType(project), project))
         	return true;
         return false;
     }
@@ -945,6 +949,127 @@
     }
 
     /**
+     * Resolving the type of an expression on an XMLish object always returns *,
+     * but this function returns the actual resolved type, if available.
+     * 
+     * @param iNode The node you want to resolve
+     * @param project an ICompilerProject for the current project.
+     * @return The type of the underlying expression, or null.
+     */
+    public static IDefinition resolveTypeXML(IExpressionNode iNode, ICompilerProject project)
+    {
+        IDefinition def = resolveXML(iNode, project);
+        if(def == null)
+        {
+            return null;
+        }
+        if (def instanceof IFunctionDefinition)
+        {
+            IFunctionDefinition functionDef = (IFunctionDefinition) def;
+            return functionDef.resolveReturnType(project);
+        }
+        return def.resolveType(project);
+    }
+
+    /**
+     * Resolving an expression on an XMLish object always returns null, but this
+     * function returns the actual resolved definition, if available.
+     * 
+     * @param iNode The node you want to resolve
+     * @param project an ICompilerProject for the current project.
+     * @return The definition of the underlying expression, or null.
+     */
+    public static IDefinition resolveXML(IExpressionNode iNode, ICompilerProject project)
+    {
+        if (iNode instanceof IFunctionCallNode)
+        {
+            IFunctionCallNode functionCall = (IFunctionCallNode) iNode;
+            IExpressionNode nameNode = functionCall.getNameNode();
+            if (nameNode instanceof IMemberAccessExpressionNode)
+            {
+                IMemberAccessExpressionNode memberAccess = (IMemberAccessExpressionNode) nameNode;
+                nameNode = memberAccess.getRightOperandNode();
+            }
+            if (nameNode instanceof IIdentifierNode)
+            {
+                IIdentifierNode identifierNode = (IIdentifierNode) nameNode;
+                IDefinition resolvedDef = identifierNode.resolve(project);
+                if (resolvedDef != null && isXMLish(resolvedDef.getParent(), project))
+                {
+                    if (resolvedDef instanceof IFunctionDefinition
+                            && !(resolvedDef instanceof IAccessorDefinition))
+                    {
+                        //method call on XML or XMLList instance
+                        return resolvedDef;
+                    }
+                }
+            }
+            return null;
+        }
+
+        if (iNode instanceof IIdentifierNode)
+        {
+            IIdentifierNode identifierNode = (IIdentifierNode) iNode;
+            IDefinition resolvedDef = identifierNode.resolve(project);
+            if (resolvedDef != null && isXMLish(resolvedDef.getParent(), project))
+            {
+                if (resolvedDef.isPrivate() || resolvedDef.isProtected())
+                {
+                    //private/protected member inside the XML or XMLList class
+                    return resolvedDef;
+                }
+            }
+        }
+        if (iNode instanceof IMemberAccessExpressionNode)
+        {
+            IMemberAccessExpressionNode memberAccess = (IMemberAccessExpressionNode) iNode;
+            IExpressionNode nameNode = memberAccess.getRightOperandNode();
+            return resolveXML(nameNode, project);
+        }
+        return null;
+    }
+
+    /**
+     * Determine if the definition passed in is one of the XML types (XML or
+     * XMLList) These classes are unrelated, but behave in similar manners.
+     * 
+     * @param def the {@link IDefinition} to check
+     * @param project the {@link ICompilerProject} in which to look up types
+     * @return true if definition is the built-in XML or XMLList type.
+     */
+    public static boolean isXMLish(IDefinition def, ICompilerProject project)
+    {
+        IDefinition xmlDef = project.getBuiltinType(IASLanguageConstants.BuiltinType.XML);
+        IDefinition xmlListDef = project.getBuiltinType(IASLanguageConstants.BuiltinType.XMLLIST);
+        return (xmlDef != null && def == xmlDef) ||
+               (xmlListDef != null && def == xmlListDef);
+    }
+    
+    /**
+     * Determines if an expression is a toString() function call.
+     */
+    public static boolean isToStringFunctionCall(IExpressionNode node, ICompilerProject project)
+    {
+        if(!(node instanceof IFunctionCallNode))
+        {
+            return false;
+        }
+        IFunctionCallNode functionCall = (IFunctionCallNode) node;
+    	IExpressionNode nameExpression = functionCall.getNameNode();
+    	if (nameExpression instanceof IMemberAccessExpressionNode)
+    	{
+    		IMemberAccessExpressionNode memberAccess = (IMemberAccessExpressionNode) nameExpression;
+    		IExpressionNode rightNode = memberAccess.getRightOperandNode();
+            if (rightNode instanceof IIdentifierNode)
+            {
+                IIdentifierNode rightIdentifier = (IIdentifierNode) rightNode;
+                return rightIdentifier.getName().equals("toString");
+            }
+    	}
+    	return false;
+    }
+
+    /**
      *  Get the type of a node's base expression as a string.
      *  @param node the node whose base's type is desired.
      *  @return the type string, or null if none found.
@@ -1200,6 +1325,21 @@
     }
 
     /**
+     *  Is this function node contained within another function node?
+     *  @param iNode - the node of interest.
+     *  @return true if the function node is a closure
+     */
+    public static boolean isFunctionClosure(IFunctionNode functionNode)
+    {
+        IScopedNode containingScope = functionNode.getContainingScope();
+        if (containingScope == null)
+        {
+            return false;
+        }
+        return containingScope.getParent() instanceof IFunctionNode;
+    }
+
+    /**
      *  Is the given node in a class with a base class definition?
      *  @param iNode - the node of interest.
      *  @return true if the node is in a class with a base class.
@@ -2492,6 +2632,36 @@
     }
     
     /**
+     * Checks that a given function's parameters have a type, and logs a problem if not
+     * 
+     * @param scope is the scope where problems are to be logged
+     * @param node is the function node that is being checked (used for location reporting)
+     * @param func is the definition of the function to be checked.
+     */
+    public static void checkParametersHaveNoTypeDeclaration(LexicalScope scope, IFunctionNode node, IFunctionDefinition func)
+    {
+        for (IParameterNode paramNode : node.getParameterNodes())
+        {
+            IExpressionNode paramType = paramNode.getVariableTypeNode();
+
+            // check for parameter type declaration
+            if (paramType == null)
+            {
+                scope.addProblem(new ParameterHasNoTypeDeclarationProblem(paramNode, paramNode.getName(), node.getName()));
+            }
+            else if(paramType.getAbsoluteStart() == -1 && paramType.getAbsoluteEnd() == -1
+                    && paramType instanceof ILanguageIdentifierNode)
+            {
+                ILanguageIdentifierNode identifier = (ILanguageIdentifierNode) paramType;
+                if (identifier.getKind().equals(LanguageIdentifierKind.ANY_TYPE))
+                {
+                    scope.addProblem(new ParameterHasNoTypeDeclarationProblem(paramNode, paramNode.getName(), node.getName()));
+                }
+            }
+        }
+    }
+    
+    /**
      * Checks that a given function definition has a return type, and logs a problem if not
      * 
      * @param scope is the scope where problems are to be logged
@@ -2889,13 +3059,44 @@
     }
 
     /**
+     *  Can the subject be abstract?
+     *  @param iNode - an AST node in (or at the border of) the function.
+     *  @return true if the definition is allowed to be abstract
+     */
+    public static boolean canBeAbstract(IASNode iNode, ICompilerProject project)
+    {
+        if(iNode instanceof IClassNode)
+        {
+            IClassNode classNode = (IClassNode) iNode;
+            IClassDefinition classDef = classNode.getDefinition();
+            return !classDef.isFinal();
+        }
+        else if(iNode instanceof IFunctionNode)
+        {
+            IFunctionNode funcNode = (IFunctionNode) iNode;
+            IFunctionDefinition funcDef = funcNode.getDefinition();
+            IDefinition parentDef = funcDef.getParent();
+            if (parentDef instanceof IClassDefinition)
+            {
+                return parentDef.isAbstract()
+                        && !funcDef.isStatic()
+                        && !funcDef.isFinal()
+                        && !funcDef.isConstructor()
+                        && !(funcDef instanceof IAccessorDefinition);
+            }
+            return false;
+        }
+        return false;
+    }
+
+    /**
      *  Does the subject function require a non-void return value?
      *  @param iNode - an AST node in (or at the border of) the function.
      *  @return true if the function's definition is known, the definition's
      *    return type is known (and the function is not a constructor),
      *    and the return type is not void or *
      */
-    public static boolean functionMustReturnValue(IASNode iNode, ICompilerProject project)
+    public static boolean functionMustReturnValue(IASNode iNode, boolean allowAbstract, ICompilerProject project)
     {
         FunctionDefinition func_def = SemanticUtils.getFunctionDefinition(iNode);
 
@@ -2908,7 +3109,8 @@
                 return_type == null ||
                 return_type.equals(ClassDefinition.getVoidClassDefinition()) ||
                 return_type.equals(ClassDefinition.getAnyTypeClassDefinition()) ||
-                func_def.isConstructor()
+                func_def.isConstructor() ||
+                (allowAbstract && canBeAbstract(iNode, project) && func_def.isAbstract())
             );
         }
         else
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/targets/RoyaleAppSWFTarget.java b/compiler/src/main/java/org/apache/royale/compiler/internal/targets/RoyaleAppSWFTarget.java
index 06fe9c2..597fbf4 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/targets/RoyaleAppSWFTarget.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/targets/RoyaleAppSWFTarget.java
@@ -47,6 +47,7 @@
 import org.apache.royale.abc.visitors.IMethodBodyVisitor;
 import org.apache.royale.abc.visitors.IMethodVisitor;
 import org.apache.royale.abc.visitors.ITraitVisitor;
+import org.apache.royale.compiler.common.DependencyType;
 import org.apache.royale.compiler.common.IEmbedResolver;
 import org.apache.royale.compiler.config.Configuration;
 import org.apache.royale.compiler.config.RSLSettings;
@@ -70,6 +71,7 @@
 import org.apache.royale.compiler.internal.definitions.ClassDefinition;
 import org.apache.royale.compiler.internal.definitions.DefinitionBase;
 import org.apache.royale.compiler.internal.definitions.NamespaceDefinition;
+import org.apache.royale.compiler.internal.projects.DependencyGraph;
 import org.apache.royale.compiler.internal.projects.RoyaleProject;
 import org.apache.royale.compiler.internal.scopes.ASProjectScope;
 import org.apache.royale.compiler.internal.tree.mxml.MXMLFileNode;
@@ -544,6 +546,16 @@
 
             // If there's more dependencies introduced by CSS, the loop continues.
             done = !allCompilationUnitsInTarget.addAll(cssDependencies);
+            if (done)
+            {
+            	ClassDefinition rootDef = getRootClassDefinition();
+	            ICompilationUnit rootClassCompilationUnit = project.getScope().getCompilationUnitForDefinition(rootDef);
+	            DependencyGraph graph = royaleProject.getDependencyGraph();
+	            for (ICompilationUnit cu : cssDependencies)
+	            {
+	            	graph.addDependency(rootClassCompilationUnit, cu, DependencyType.EXPRESSION);
+	            }
+            }
         }
 
         delegate.cssCompilationSession.cssDocuments.addAll(activatedStyleSheets.sort());
@@ -841,7 +853,6 @@
             
             this.cssCompilationSession = new CSSCompilationSession();
             this.cssCompilationSession.setKeepAllTypeSelectors(targetSettings.keepAllTypeSelectors());
-            this.cssCompilationSession.setExcludeDefaultsCSSFiles(targetSettings.getExcludeDefaultsCSSFiles());
         }
         
         private final IClassDefinition mainApplicationClassDefinition;
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/targets/RoyaleTarget.java b/compiler/src/main/java/org/apache/royale/compiler/internal/targets/RoyaleTarget.java
index 933d9a6..6a36dec 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/targets/RoyaleTarget.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/targets/RoyaleTarget.java
@@ -20,8 +20,11 @@
 package org.apache.royale.compiler.internal.targets;
 
 import java.io.File;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -755,13 +758,28 @@
      */
     public void addProductInfoToSWF(ISWF swf)
     {
+    	long compileDate = new Date().getTime();
+    	String rdfDate = targetSettings.getSWFMetadataDate();
+    	String rdfDateFormat = targetSettings.getSWFMetadataDateFormat();
+    	if (rdfDate != null && rdfDateFormat != null)
+    	{
+    		try {
+    			SimpleDateFormat sdf = new SimpleDateFormat(rdfDateFormat);
+    			compileDate = sdf.parse(rdfDate).getTime();
+    		} catch (ParseException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (IllegalArgumentException e1) {
+				e1.printStackTrace();
+			}
+    	}
         // Add product info to the swf.
         ProductInfoTag productInfo = new ProductInfoTag(Product.ROYALE,
                 Edition.NONE,
                 (byte)Integer.parseInt(VersionInfo.FLEX_MAJOR_VERSION),
                 (byte)Integer.parseInt(VersionInfo.FLEX_MINOR_VERSION),
                 VersionInfo.getBuildLong(),
-                0);
+                compileDate);
         swf.setProductInfo(productInfo);
     }
 }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/targets/SWCTarget.java b/compiler/src/main/java/org/apache/royale/compiler/internal/targets/SWCTarget.java
index 8088ec9..dbeafc5 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/targets/SWCTarget.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/targets/SWCTarget.java
@@ -22,6 +22,8 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -318,6 +320,22 @@
         
         if (contents != null)
         {
+        	long fileDate = 0;
+        	String metadataDate = targetSettings.getSWFMetadataDate();
+        	if (metadataDate != null)
+        	{
+        		String metadataFormat = targetSettings.getSWFMetadataDateFormat();
+        		try {
+        			SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
+        			fileDate = sdf.parse(metadataDate).getTime();
+        		} catch (ParseException e) {
+    				// TODO Auto-generated catch block
+    				e.printStackTrace();
+    			} catch (IllegalArgumentException e1) {
+    				e1.printStackTrace();
+    			}
+        		fileSpec.setLastModified(fileDate);
+        	}
             swc.addFile(path, fileSpec.getLastModified(), contents);
         }
         else    
@@ -532,7 +550,22 @@
         for (final IDefinition def : fsResult.getExternallyVisibleDefinitions())
         {
             script.addDefinition(def.getQualifiedName());
-            script.setLastModified(cu.getSyntaxTreeRequest().get().getLastModified());
+            long mod = cu.getSyntaxTreeRequest().get().getLastModified();
+        	String metadataDate = targetSettings.getSWFMetadataDate();
+        	if (metadataDate != null)
+        	{
+        		String metadataFormat = targetSettings.getSWFMetadataDateFormat();
+        		try {
+        			SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
+        			mod = sdf.parse(metadataDate).getTime();
+        		} catch (ParseException e) {
+    				// TODO Auto-generated catch block
+    				e.printStackTrace();
+    			} catch (IllegalArgumentException e1) {
+    				e1.printStackTrace();
+    			}
+        	}            
+            script.setLastModified(mod);
             
             if (definitionsToBuild != null)
                 definitionsToBuild.add(def);
@@ -661,7 +694,11 @@
         rootCompilationUnits.addAll(getIncludesCompilationUnits());
         rootCompilationUnits.addAll(getIncludeLibrariesCompilationUnits());
         
-        return new Target.RootedCompilationUnits(rootCompilationUnits, problems);
+        Target.RootedCompilationUnits units = new Target.RootedCompilationUnits(rootCompilationUnits, problems);
+        Set<ICompilationUnit> unitSet = units.getUnits();
+//        for (ICompilationUnit cu : unitSet)
+//        	System.out.println(cu.getName());
+        return units;
     }
     
     @Override
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/targets/Target.java b/compiler/src/main/java/org/apache/royale/compiler/internal/targets/Target.java
index cc16eb7..8acd14e 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/targets/Target.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/targets/Target.java
@@ -26,9 +26,12 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
 
 import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.definitions.references.IResolvedQualifiersReference;
@@ -366,7 +369,20 @@
                     return Collections.emptySet();
             }
         }
-        return visitedSet;
+        TreeSet<ICompilationUnit> sortedSet = new TreeSet<ICompilationUnit>(new Comparator<ICompilationUnit>()
+        {
+            @Override
+            public int compare(ICompilationUnit o1, ICompilationUnit o2)
+            {
+                return o1.getName().compareTo(o2.getName());
+            }
+        });
+        sortedSet.addAll(visitedSet);
+//        System.out.println("visited set");
+//        for (ICompilationUnit visited : sortedSet)
+//        	System.out.println(visited.getName());
+//        System.out.println("end visited set");
+        return sortedSet;
     }
     
     protected DirectDependencies getDirectDependencies(ICompilationUnit cu) throws InterruptedException
@@ -766,11 +782,19 @@
         {
             assert units != null;
             assert problems != null;
-            this.units = units;
+            this.units = new TreeSet<ICompilationUnit>(new Comparator<ICompilationUnit>()
+            {
+                @Override
+                public int compare(ICompilationUnit o1, ICompilationUnit o2)
+                {
+                    return o1.getName().compareTo(o2.getName());
+                }
+            });
+            this.units.addAll(units);
             this.problems = problems;
         }
         
-        private final Set<ICompilationUnit> units;
+        private final SortedSet<ICompilationUnit> units;
         private final Iterable<ICompilerProblem> problems;
         
         public Set<ICompilationUnit> getUnits()
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BaseDefinitionNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BaseDefinitionNode.java
index a1d9609..c45def6 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BaseDefinitionNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BaseDefinitionNode.java
@@ -401,6 +401,8 @@
             db.setOverride();
         if (hasModifier(ASModifier.STATIC))
             db.setStatic();
+        if (hasModifier(ASModifier.ABSTRACT))
+            db.setAbstract();
     }
 
     protected void fillInMetadata(DefinitionBase definition)
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BaseLiteralContainerNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BaseLiteralContainerNode.java
index 625d9e4..f1496df 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BaseLiteralContainerNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BaseLiteralContainerNode.java
@@ -37,7 +37,8 @@
     /**
      * Constructor.
      */
-    public BaseLiteralContainerNode(LiteralNode baseTypeNode)
+    @SuppressWarnings("incomplete-switch")
+	public BaseLiteralContainerNode(LiteralNode baseTypeNode)
     {
         this.baseTypeNode = baseTypeNode;
         baseTypeNode.setParent(this);
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BinaryOperatorNodeBase.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BinaryOperatorNodeBase.java
index d51c82d..03dae65 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BinaryOperatorNodeBase.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BinaryOperatorNodeBase.java
@@ -282,7 +282,7 @@
     protected void fillInOffsets()
     {
         if (rightOperandNode == null && leftOperandNode == null && operatorStart != -1)
-            span(operatorStart, operatorStart + 1, -1, -1);
+            span(operatorStart, operatorStart + 1, -1, -1, -1, -1);
         else
             super.fillInOffsets();
     }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BinaryOperatorPlusNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BinaryOperatorPlusNode.java
index 771b4aa..7f4bcea 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BinaryOperatorPlusNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BinaryOperatorPlusNode.java
@@ -21,6 +21,7 @@
 
 import org.apache.royale.compiler.constants.IASLanguageConstants.BuiltinType;
 import org.apache.royale.compiler.definitions.ITypeDefinition;
+import org.apache.royale.compiler.internal.semantics.SemanticUtils;
 import org.apache.royale.compiler.parsing.IASToken;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.ASTNodeID;
@@ -83,8 +84,8 @@
         
         // If we're adding two XML-ish (i.e., XML or XMLList) objects,
         // then the result is XMLList.
-        if (IdentifierNode.isXMLish(leftType, project) &&
-            IdentifierNode.isXMLish(rightType, project))
+        if (SemanticUtils.isXMLish(leftType, project) &&
+            SemanticUtils.isXMLish(rightType, project))
         {
             return project.getBuiltinType(BuiltinType.XMLLIST);
         }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/ClassNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/ClassNode.java
index 38e094b..484f0a8 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/ClassNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/ClassNode.java
@@ -361,6 +361,16 @@
         {
             if (contentsNode.getChild(i) instanceof IDefinitionNode)
                 names.add(((IDefinitionNode)contentsNode.getChild(i)));
+            else if (contentsNode.getChild(i).getNodeID() == ASTNodeID.ConfigBlockID)
+            {
+            	ConfigConditionBlockNode configNode = (ConfigConditionBlockNode)contentsNode.getChild(i);
+            	int configChildCount = configNode.getChildCount();
+            	for (int j = 0; j < configChildCount; j++)
+            	{
+                    if (configNode.getChild(j) instanceof IDefinitionNode)
+                        names.add(((IDefinitionNode)configNode.getChild(j)));            		
+            	}            	
+            }
         }
         return names.toArray(new IDefinitionNode[0]);
     }
@@ -503,10 +513,10 @@
             // so we'll create one and add it to the ClassNode
             IdentifierNode constructorNameNode = new IdentifierNode(getName());
             constructorNameNode.setReferenceValue(getDefinition());
-            constructorNameNode.span(getNameAbsoluteStart(), getNameAbsoluteEnd(), -1, -1);
+            constructorNameNode.span(getNameAbsoluteStart(), getNameAbsoluteEnd(), -1, -1, -1, -1);
             defaultConstructorNode = new FunctionNode(null, constructorNameNode);
             NamespaceIdentifierNode pub = new NamespaceIdentifierNode(INamespaceConstants.public_);
-            pub.span(-1, -1, -1, -1);
+            pub.span(-1, -1, -1, -1, -1, -1);
             defaultConstructorNode.setNamespace(pub);
             defaultConstructorNode.normalize(true);
             defaultConstructorNode.setParent(contentsNode);
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/ConfigConditionBlockNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/ConfigConditionBlockNode.java
index 62080ea..c0998f4 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/ConfigConditionBlockNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/ConfigConditionBlockNode.java
@@ -33,7 +33,7 @@
  */
 public final class ConfigConditionBlockNode extends BlockNode
 {
-    private final boolean enabled;
+    private boolean enabled;
 
     /**
      * Create a enabled or disabled configuration config block.
@@ -58,6 +58,24 @@
         else
             return 0;
     }
+
+    @Override
+    protected void fillInOffsets()
+    {
+        boolean oldEnabled = enabled;
+        enabled = true;
+        super.fillInOffsets();
+        enabled = oldEnabled;
+    }
+
+    @Override
+    public void normalize(boolean fillInOffsets)
+    {
+        boolean oldEnabled = enabled;
+        enabled = true;
+        super.normalize(fillInOffsets);
+        enabled = oldEnabled;
+    }
     
     @Override
     protected boolean buildInnerString(StringBuilder sb)
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/DynamicAccessNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/DynamicAccessNode.java
index 49cad6e..8df9fae 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/DynamicAccessNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/DynamicAccessNode.java
@@ -19,6 +19,9 @@
 
 package org.apache.royale.compiler.internal.tree.as;
 
+import org.apache.royale.compiler.definitions.IAppliedVectorDefinition;
+import org.apache.royale.compiler.definitions.ITypeDefinition;
+import org.apache.royale.compiler.internal.semantics.SemanticUtils;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IDynamicAccessNode;
@@ -70,9 +73,28 @@
     @Override
     public boolean isDynamicExpression(ICompilerProject project)
     {
+        ITypeDefinition leftType = getLeftOperandNode().resolveType(project);
+        if (leftType instanceof IAppliedVectorDefinition)
+        {
+            return super.isDynamicExpression(project);
+        }
         return true;
     }
     
+    @Override
+    public ITypeDefinition resolveType(ICompilerProject project)
+    {
+        ITypeDefinition leftType = getLeftOperandNode().resolveType(project);
+        if (leftType instanceof IAppliedVectorDefinition)
+        {
+            if (SemanticUtils.isNumericType(getRightOperandNode().resolveType(project), project)) {
+                IAppliedVectorDefinition vectorDef = (IAppliedVectorDefinition) leftType;
+                return vectorDef.resolveElementType(project);
+            }
+        }
+        return super.resolveType(project);
+    }
+    
     //
     // OperatorNodeBase overrides
     //
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FullNameNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FullNameNode.java
index c23fec7..92c9709 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FullNameNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FullNameNode.java
@@ -71,7 +71,11 @@
         super(left, operator, right);
         
         if (right != null)
+        {
             setEnd(right.getAbsoluteEnd());
+            setEndLine(right.getEndLine());
+            setEndColumn(right.getEndColumn());
+        }
     }
 
     protected FullNameNode(MemberAccessExpressionNode node)
@@ -145,7 +149,11 @@
         super.setRightOperandNode(right);
         
         if (right != null)
+        {
             setEnd(right.getAbsoluteEnd());
+            setEndLine(right.getEndLine());
+            setEndColumn(right.getEndColumn());
+        }
     }
     
     //
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FunctionCallNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FunctionCallNode.java
index 255eee5..b0628fb 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FunctionCallNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FunctionCallNode.java
@@ -23,10 +23,7 @@
 
 import org.apache.royale.compiler.constants.IASLanguageConstants;
 import org.apache.royale.compiler.constants.IASLanguageConstants.BuiltinType;
-import org.apache.royale.compiler.definitions.IAccessorDefinition;
-import org.apache.royale.compiler.definitions.IDefinition;
-import org.apache.royale.compiler.definitions.IFunctionDefinition;
-import org.apache.royale.compiler.definitions.ITypeDefinition;
+import org.apache.royale.compiler.definitions.*;
 import org.apache.royale.compiler.parsing.IASToken;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.ASTNodeID;
@@ -211,8 +208,17 @@
             //  new foo() returns the * type
             if (getNewKeywordNode() != null)
                 return project.getBuiltinType(BuiltinType.ANY_TYPE);
-            else
-                return ((IFunctionDefinition)calledFunction).resolveReturnType(project);
+            else {
+                //special case: removeAt on a Vector needs to resolve its return type to type 'T' (element type), not 'Object' (as it does with Array method)
+                if (calledFunction.getQualifiedName().equals("removeAt")
+                    && calledFunction.getContainingScope() != null
+                    && calledFunction.getContainingScope().getDefinition() instanceof IAppliedVectorDefinition)
+                {
+                    return ((IAppliedVectorDefinition)(calledFunction.getContainingScope().getDefinition())).resolveElementType(project);
+                } else {
+                    return ((IFunctionDefinition)calledFunction).resolveReturnType(project);
+                }
+            }
         }
         else if (calledFunction instanceof ITypeDefinition)
         {
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FunctionNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FunctionNode.java
index c48154b..54c836c 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FunctionNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FunctionNode.java
@@ -36,8 +36,10 @@
 import org.apache.royale.compiler.common.IImportTarget;
 import org.apache.royale.compiler.config.CompilerDiagnosticsConstants;
 import org.apache.royale.compiler.constants.IASLanguageConstants;
+import org.apache.royale.compiler.constants.IMetaAttributeConstants;
 import org.apache.royale.compiler.constants.INamespaceConstants;
 import org.apache.royale.compiler.definitions.IDefinition;
+import org.apache.royale.compiler.definitions.INamespaceDefinition;
 import org.apache.royale.compiler.definitions.IFunctionDefinition.FunctionClassification;
 import org.apache.royale.compiler.definitions.IParameterDefinition;
 import org.apache.royale.compiler.definitions.references.IReference;
@@ -74,6 +76,7 @@
 import org.apache.royale.compiler.tree.as.IScopedNode;
 import org.apache.royale.compiler.tree.as.ITypeNode;
 import org.apache.royale.compiler.tree.as.IVariableNode;
+import org.apache.royale.compiler.tree.metadata.IMetaTagNode;
 import org.apache.royale.compiler.workspaces.IWorkspace;
 
 import com.google.common.base.Predicate;
@@ -165,6 +168,12 @@
      * Save the problems until later if we were parsed from somewhere we don't have a problems collection
      */
     private Collection<ICompilerProblem> parseProblems;
+
+    /**
+     * Indicates whether we've called rememberLocalFunction() on the parent
+     * function yet (if a parent function even exists in the first place) -JT
+     */
+    private boolean isRemembered = false;
     
     //
     // NodeBase overrides
@@ -203,12 +212,24 @@
     @Override
     protected void analyze(EnumSet<PostProcessStep> set, ASScope scope, Collection<ICompilerProblem> problems)
     {
-        if (set.contains(PostProcessStep.POPULATE_SCOPE))
+        if (!isRemembered)
         {
+            //previously, we remembered local functions only during
+            //POPULATE_SCOPE. however, in MXML, functions get created multiple
+            //times, and the second time around, analyze() is NOT called with
+            //POPULATE_SCOPE. this causes our function to be forgotten.
+            //better to check if we've remembered or not no matter which steps
+            //were passed in. -JT
             final IFunctionNode parentFunctionNode = (IFunctionNode)getAncestorOfType(IFunctionNode.class);
             if (parentFunctionNode != null)
+            {
+                isRemembered = true;
                 parentFunctionNode.rememberLocalFunction(this);
-        
+            }
+        }
+
+        if (set.contains(PostProcessStep.POPULATE_SCOPE))
+        {
             FunctionDefinition definition = buildDefinition();
             setDefinition(definition);
 
@@ -346,10 +367,32 @@
         
         if (isConstructor())
         {
-            if (namespaceNode != null && namespaceNode.getName().equals(INamespaceConstants.public_))
+            if (namespaceNode != null
+                    && (namespaceNode.getName().equals(INamespaceConstants.public_) || namespaceNode.getName().equals(INamespaceConstants.private_)))
+            {
+                // if the existing node is already public or private, return it
                 return namespaceNode;
+            }
+            IASNode parentNode = getParent();
+            if (parentNode instanceof IDefinitionNode)
+            {
+                IDefinitionNode defNode = (IDefinitionNode) parentNode;
+                IMetaTagNode[] metaTagNodes = defNode.getMetaTags().getTagsByName(IMetaAttributeConstants.ATTRIBUTE_PRIVATE_CONSTRUCTOR);
+                if (metaTagNodes != null && metaTagNodes.length > 0)
+                {
+                    // if the parent class has [RoyalePrivateConstructor]
+                    // metadata, the constructor should be considered private
+                    // and we should generate a fake namespace node
+                    NamespaceIdentifierNode priv = new NamespaceIdentifierNode(INamespaceConstants.private_);
+                    priv.span(-1, -1, -1, -1, -1, -1);
+                    priv.setDecorationTarget(this);
+                    return priv;
+                }
+            }
+            // if there is no namespace node, the namespace defaults to public
+            // and we'll generate a fake node
             NamespaceIdentifierNode pub = new NamespaceIdentifierNode(INamespaceConstants.public_);
-            pub.span(-1, -1, -1, -1);
+            pub.span(-1, -1, -1, -1, -1, -1);
             pub.setDecorationTarget(this);
             return pub;
         }
@@ -364,11 +407,12 @@
         if (ns != null)
         {
             String nameString = ns.getName();
-            // If public, just return it.
-            if (nameString.equals(INamespaceConstants.public_))
+            // If public or private, just return it.
+            if (nameString.equals(INamespaceConstants.public_) || nameString.equals(INamespaceConstants.private_))
                 return nameString;
 
-            // Otherwise, check to see if we are a constructor.
+            // Otherwise, check to see if we are a constructor and always return
+            // public
             if (isConstructor())
                 return INamespaceConstants.public_;
             
@@ -631,8 +675,16 @@
                         classNode.constructorNode = this;
                     }
                 }
+                // if the namespace reference is private, don't change it
+                if(!(funcDef.getNamespaceReference() instanceof INamespaceDefinition.IPrivateNamespaceDefinition))
+                {
+                    funcDef.setNamespaceReference(NamespaceDefinition.getCodeModelImplicitDefinitionNamespace());
+                }
             }
-            funcDef.setNamespaceReference(NamespaceDefinition.getCodeModelImplicitDefinitionNamespace());
+            else
+            {
+                funcDef.setNamespaceReference(NamespaceDefinition.getCodeModelImplicitDefinitionNamespace());
+            }
         }
     }
 
@@ -902,6 +954,11 @@
             {
                 return problem.getLine() == line;
             }
+            @Override
+            public boolean test(ICompilerProblem input)
+            {
+                return apply(input);
+            }
         };
     }
 
@@ -917,6 +974,11 @@
             {
                 return problemClass.isInstance(problem);
             }
+            @Override
+            public boolean test(ICompilerProblem input)
+            {
+                return apply(input);
+            }
         };
     }
 
@@ -1040,19 +1102,5 @@
             localFunctions = new ArrayList<IFunctionNode>();
         
         localFunctions.add(value);
-    }  
-
-    private boolean emitLocalFunctions;
-    
-    @Override
-    public boolean getEmittingLocalFunctions()
-    {
-        return emitLocalFunctions;
-    }
-    
-    @Override
-    public void setEmittingLocalFunctions(boolean emit)
-    {
-        emitLocalFunctions = emit;
     }
 }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/IdentifierNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/IdentifierNode.java
index ccad9d6..3ba32a1 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/IdentifierNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/IdentifierNode.java
@@ -104,22 +104,6 @@
     }
 
     /**
-     * Determine if the definition passed in is one of the XML types (XML or
-     * XMLList) These classes are unrelated, but behave in similar manners.
-     * 
-     * @param def the {@link IDefinition} to check
-     * @param project the {@link ICompilerProject} in which to look up types
-     * @return true if definition is the built-in XML or XMLList type.
-     */
-    public static boolean isXMLish(IDefinition def, ICompilerProject project)
-    {
-        IDefinition xmlDef = project.getBuiltinType(IASLanguageConstants.BuiltinType.XML);
-        IDefinition xmlListDef = project.getBuiltinType(IASLanguageConstants.BuiltinType.XMLLIST);
-        return (xmlDef != null && def == xmlDef) ||
-               (xmlListDef != null && def == xmlListDef);
-    }
-
-    /**
      * Constructor.
      */
     public IdentifierNode(String name)
@@ -323,6 +307,7 @@
         return true;
     }
 
+    private IDefinition idDef = null;
     //
     // ExpressionNodeBase overrides
     //
@@ -330,6 +315,9 @@
     @Override
     public IDefinition resolve(ICompilerProject project)
     {
+    	if (DefinitionBase.getPerformanceCachingEnabled() && idDef != null)
+    		return idDef;
+    	
         ASScope asScope = getASScope();
 
         if (asScope == null)
@@ -391,7 +379,10 @@
         {
             if (qualifier == null)
             {
-                result = asScope.findProperty(project, name, getDependencyType(), isTypeRef());
+            	DependencyType dt = getDependencyType();
+                result = asScope.findProperty(project, name, dt, isTypeRef());
+                if (result != null && name.equals("graphics") && (result.getParent() instanceof ITypeDefinition) && ((ITypeDefinition)(result.getParent())).isInstanceOf("mx.core.UIComponent", project))
+                	result = asScope.findProperty(project, "royalegraphics", getDependencyType(), isTypeRef());
                 // ASVariableTests_localVarSameNameAsPrivateMethod
                 if (isLegacyCodegen(project) && result != null && getParent().getNodeID() == ASTNodeID.FunctionCallID && result instanceof VariableDefinition)
                 {
@@ -457,6 +448,7 @@
         		((RoyaleProject)project).addToAPIReport(result);
         }
         
+        idDef = result;
         return result;
     }
 
@@ -467,7 +459,7 @@
 
         if (def != null)
         {
-            if (isXMLish(def.getParent(), project))
+            if (SemanticUtils.isXMLish(def.getParent(), project))
             {
                 // XML and XMLList members should be treated as '*' because any access could
                 // resolve to some content inside the XML (i.e. it has a child tag named 'name').
@@ -878,7 +870,7 @@
         IDefinition result = null;
 
         // Determine baseType, the type of 'a' (the left-hand-side of the member access operator).
-        IDefinition baseType = null;
+        ITypeDefinition baseType = null;
         ExpressionNodeBase baseExpr = getBaseExpression();
         if (baseExpr != null)
         {
@@ -901,7 +893,7 @@
                     // and x is type XML you would get a can't-convert-Object-to-String
                     // problem, but there is lots of existing source code that expects
                     // this to compile with no cast.
-                    if (!((RoyaleProject)project).useStrictXML() && isXMLish(baseType, project))
+                    if (!((RoyaleProject)project).useStrictXML() && SemanticUtils.isXMLish(baseType, project))
                         return null;
                     
                     if (baseExpr instanceof IdentifierNode)
@@ -920,6 +912,12 @@
                 }
                 if (qualifier != null)
                     result = asScope.getQualifiedPropertyFromDef(project, baseType, name, qualifier, isSuper);
+                else if (name.equals("graphics") && baseType.isInstanceOf("mx.core.UIComponent", project))
+                {
+                	result = asScope.getPropertyFromDef(project, baseType, "royalegraphics", isSuper);
+                    if (result == null)
+                        result = asScope.getPropertyFromDef(project, baseType, name, isSuper);
+                }
                 else
                     result = asScope.getPropertyFromDef(project, baseType, name, isSuper);
             }
@@ -1031,7 +1029,7 @@
             // Can't early bind to XML/XMLList properties as they may be hidden by the unknown contents
             // of the XML itself, i.e. a child tag named 'parent'
             // Matches ASC behavior.
-            if (!isXMLish(def.getParent(), project))
+            if (!SemanticUtils.isXMLish(def.getParent(), project))
                 return true;
         }
         return false;
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/LanguageIdentifierNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/LanguageIdentifierNode.java
index 89175d5..090717b 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/LanguageIdentifierNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/LanguageIdentifierNode.java
@@ -464,7 +464,8 @@
      * 
      * @return The Context that this expression occurs in
      */
-    public Context getContext()
+    @SuppressWarnings("incomplete-switch")
+	public Context getContext()
     {
         IASNode p = getParent();
 
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/LiteralNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/LiteralNode.java
index 1f60b9f..f9eb2f8 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/LiteralNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/LiteralNode.java
@@ -119,7 +119,8 @@
     // NodeBase overrides
     //
 
-    @Override
+    @SuppressWarnings("incomplete-switch")
+	@Override
     public ASTNodeID getNodeID()
     {
         switch (type)
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/NamespaceAccessExpressionNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/NamespaceAccessExpressionNode.java
index 175f500..ae8e987 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/NamespaceAccessExpressionNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/NamespaceAccessExpressionNode.java
@@ -41,7 +41,7 @@
     {
         super(operator, left instanceof IdentifierNode ? new NamespaceIdentifierNode((IdentifierNode)left) : left, right);
         
-        leftOperandNode.span(left.getAbsoluteStart(), left.getAbsoluteEnd(), left.getLine(), left.getColumn());
+        leftOperandNode.span(left.getAbsoluteStart(), left.getAbsoluteEnd(), left.getLine(), left.getColumn(), left.getEndLine(), left.getEndColumn());
     }
 
     /**
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/NamespaceIdentifierNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/NamespaceIdentifierNode.java
index bd74fd2..05238a9 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/NamespaceIdentifierNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/NamespaceIdentifierNode.java
@@ -79,7 +79,7 @@
     {
         super(node.getName());
         
-        span(node.getAbsoluteStart(), node.getAbsoluteEnd(), node.getLine(), node.getColumn());
+        span(node.getAbsoluteStart(), node.getAbsoluteEnd(), node.getLine(), node.getColumn(), node.getEndLine(), node.getEndColumn());
         setSourcePath(node.getSourcePath());
     }
 
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/NodeBase.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/NodeBase.java
index d4d9941..eef182f 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/NodeBase.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/NodeBase.java
@@ -483,13 +483,28 @@
      * @param start start offset for the node
      * @param end end offset for the node
      * @param line line number for the node
+     * @deprecated Use span(int,int,int,int,int,int) instead so that endLine and endColumn are included
      */
     public final void span(int start, int end, int line, int column)
     {
+        span(start, end, line, column, -1, -1);
+    }
+
+    /**
+     * Set the start and end offsets of the node. Used during parsing.
+     * 
+     * @param start start offset for the node
+     * @param end end offset for the node
+     * @param line line number for the node
+     */
+    public final void span(int start, int end, int line, int column, int endLine, int endColumn)
+    {
         setStart(start);
         setEnd(end);
         setLine(line);
         setColumn(column);
+        setEndLine(endLine);
+        setEndColumn(endColumn);
     }
 
     public Collection<ICompilerProblem> runPostProcess(EnumSet<PostProcessStep> set, ASScope containingScope)
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/ParameterNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/ParameterNode.java
index 51b209c..93efc2f 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/ParameterNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/ParameterNode.java
@@ -172,7 +172,7 @@
         if (typeNode == null && isRest())
         {
             typeNode = new IdentifierNode(IASLanguageConstants.Array);
-            typeNode.span(-1, -1, -1, -1);
+            typeNode.span(-1, -1, -1, -1, -1, -1);
             return;
         }
         
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/UnaryOperatorNodeBase.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/UnaryOperatorNodeBase.java
index 5145924..be92a12 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/UnaryOperatorNodeBase.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/UnaryOperatorNodeBase.java
@@ -148,7 +148,7 @@
     {
         if (operandNode == null && operatorStart != -1)
         {
-            span(operatorStart, operatorStart + 1, -1, -1);
+            span(operatorStart, operatorStart + 1, -1, -1, -1, -1);
         }
         else
         {
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/UseNamespaceNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/UseNamespaceNode.java
index 8ce1130..51a3d29 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/UseNamespaceNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/UseNamespaceNode.java
@@ -123,7 +123,7 @@
             {
                 namespaceNode = new NamespaceIdentifierNode(((IIdentifierNode)namespace).getName());
                 ((NodeBase)namespaceNode).setSourcePath(namespace.getSourcePath());
-                ((NodeBase)namespaceNode).span(namespace.getAbsoluteStart(), namespace.getAbsoluteEnd(), namespace.getLine(), namespace.getColumn());
+                ((NodeBase)namespaceNode).span(namespace.getAbsoluteStart(), namespace.getAbsoluteEnd(), namespace.getLine(), namespace.getColumn(), namespace.getEndLine(), namespace.getEndColumn());
             }
         }
     }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLBindingAttributeNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLBindingAttributeNode.java
index 1fee677..56b8247 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLBindingAttributeNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLBindingAttributeNode.java
@@ -83,6 +83,11 @@
         return attributeName;
     }
 
+    public void setName(String s)
+    {
+    	attributeName = s;
+    }
+    
     @Override
     public int getChildCount()
     {
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLBindingNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLBindingNode.java
index 19b8085..5ed122b 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLBindingNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLBindingNode.java
@@ -39,7 +39,7 @@
 /**
  * Implementation of the {@code IMXMLBindingNode} interface.
  */
-class MXMLBindingNode extends MXMLNodeBase implements IMXMLBindingNode
+public class MXMLBindingNode extends MXMLNodeBase implements IMXMLBindingNode
 {
     /**
      * Constructor
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLClassReferenceNodeBase.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLClassReferenceNodeBase.java
index 1327d7a..4c66aa4 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLClassReferenceNodeBase.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLClassReferenceNodeBase.java
@@ -51,6 +51,7 @@
 import org.apache.royale.compiler.parsing.MXMLTokenTypes;
 import org.apache.royale.compiler.problems.ICompilerProblem;
 import org.apache.royale.compiler.problems.MXMLDuplicateChildTagProblem;
+import org.apache.royale.compiler.problems.MXMLUnresolvedTagProblem;
 import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IASNode;
@@ -592,6 +593,11 @@
                         }
                 	}
                 }
+                if (processingDefaultProperty && definition == null)
+                {
+                    builder.getProblems().add(new MXMLUnresolvedTagProblem(childTag));
+                	return;
+                }
                 // Handle child tags that are something other than property/style/event tags
                 // or instance tags.
 
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLExpressionNodeBase.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLExpressionNodeBase.java
index 1bb26bc..34a9586 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLExpressionNodeBase.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLExpressionNodeBase.java
@@ -198,7 +198,7 @@
                 if (!SemanticUtils.isValidTypeConversion(expectedType, exprType, project, builder.getCompilationUnit().isInvisible()))
                 {
                     ICompilerProblem problem = new ImplicitCoercionToUnrelatedTypeProblem(
-                            expressionNode, exprType.getBaseName(), expectedType.getBaseName());
+                            expressionNode, exprType.getQualifiedName(), expectedType.getQualifiedName());
                     builder.addProblem(problem);
                 }
             }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLNodeBase.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLNodeBase.java
index 4909e2e..b511f63 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLNodeBase.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLNodeBase.java
@@ -689,6 +689,7 @@
      * @param end The ending offset of this node.
      * @param line The number of the line on which this node starts.
      * @param column This number of the column at which this node starts.
+     * @deprecated Use setLocation(String,int,int,int,int,int,int) instead
      */
     public void setLocation(String sourcePath, int start, int end, int line, int column)
     {
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLObjectNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLObjectNode.java
index 04f98a1..ef12b6f 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLObjectNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLObjectNode.java
@@ -19,7 +19,6 @@
 
 package org.apache.royale.compiler.internal.tree.mxml;
 
-import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.royale.compiler.constants.IASLanguageConstants;
@@ -28,7 +27,6 @@
 import org.apache.royale.compiler.mxml.IMXMLTagData;
 import org.apache.royale.compiler.mxml.IMXMLUnitData;
 import org.apache.royale.compiler.tree.ASTNodeID;
-import org.apache.royale.compiler.tree.mxml.IMXMLNode;
 import org.apache.royale.compiler.tree.mxml.IMXMLObjectNode;
 
 /**
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLTreeBuilder.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLTreeBuilder.java
index 557dbf2..07291f8 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLTreeBuilder.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLTreeBuilder.java
@@ -137,6 +137,7 @@
         this.compilationUnit = compilationUnit;
         this.fileSpecGetter = fileSpecGetter;
         project = compilationUnit.getProject();
+        factoryDef = (ITypeDefinition) project.resolveQNameToDefinition(project.getFactoryInterface());
         projectScope = (ASProjectScope)project.getScope();
         workspace = (Workspace)project.getWorkspace();
         this.qname = qname;
@@ -154,6 +155,8 @@
     private final IFileSpecificationGetter fileSpecGetter;
 
     private final RoyaleProject project;
+    
+    private final ITypeDefinition factoryDef;
 
     private final ASProjectScope projectScope;
 
@@ -664,7 +667,7 @@
         String typeName = (type != null) ? type.getQualifiedName() : "";
 
         // For a property of type IFactory, create an MXMLFactoryNode.
-        if (typeName.equals(project.getFactoryInterface()))
+        if (type != null && type.isInstanceOf(factoryDef, project))
         {
             if (flags.contains(TextParsingFlags.ALLOW_BINDING))
             {
@@ -791,7 +794,7 @@
 
         return instanceNode;
     }
-
+    
     /**
      * Reads an external file specified by a <code>source</code> attribute.
      * 
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/XMLBuilder.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/XMLBuilder.java
index bb5b63e..b428289 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/XMLBuilder.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/XMLBuilder.java
@@ -198,7 +198,8 @@
      * those are (these are the expressions to set the value in the XML object
      * when the TODO: PropertyChange event fires).
      */
-    void processNode(IMXMLTextData tag,
+    @SuppressWarnings("incomplete-switch")
+	void processNode(IMXMLTextData tag,
                      StringWriter sw)
     {
         switch (tag.getTextType())
@@ -284,6 +285,8 @@
         MXMLBindingNode bindingNode = new MXMLBindingNode(parent);
 
         MXMLBindingAttributeNode target = new MXMLBindingAttributeNode(bindingNode, destExpr);
+        target.setLocation(attr);
+        target.setName(attr.getName());
         destExpr.setParent(target);
         MXMLBindingAttributeNode source = new MXMLBindingAttributeNode(bindingNode, dbnode.getExpressionNode());
 
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/units/CompilationUnitBase.java b/compiler/src/main/java/org/apache/royale/compiler/internal/units/CompilationUnitBase.java
index 9e680f6..a0cef1f 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/units/CompilationUnitBase.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/units/CompilationUnitBase.java
@@ -58,6 +58,7 @@
 import org.apache.royale.compiler.internal.projects.CompilerProject;
 import org.apache.royale.compiler.internal.projects.DefinitionPriority;
 import org.apache.royale.compiler.internal.projects.DependencyGraph;
+import org.apache.royale.compiler.internal.projects.RoyaleProject;
 import org.apache.royale.compiler.internal.scopes.ASFileScope;
 import org.apache.royale.compiler.internal.scopes.ASProjectScope;
 import org.apache.royale.compiler.internal.scopes.ASProjectScope.DefinitionPromise;
@@ -1005,13 +1006,21 @@
      */
     private String computeName()
     {
-        final String filename = FilenameUtils.getName(getAbsoluteFilename()).replace('.', '_');
-        final String encodedAbsolutePath = StringEncoder.stringToHashCodeString(getAbsoluteFilename());
-        String encodedName = encodedAbsolutePath + ":" + filename;
+        String absoluteFileName = getAbsoluteFilename();
+        final String filename = FilenameUtils.getName(absoluteFileName).replace('.', '_');
         if (definitionPromises.isEmpty())
         {
+        	// conditional compilation units may not have definitionpromises
+            String encodedName = StringEncoder.stringToHashCodeString(absoluteFileName);
+            encodedName +=  ":" + filename;
             return encodedName;
         }
+        // we used to use the absolute path, but it would be different
+        // on different machines and we want builds to be binary reproducible.
+        // So we will use the first definition's QName as that should be unique
+        IDefinition def0 = getDefinitionPromises().get(0);
+        final String encodedQName = StringEncoder.stringToHashCodeString(def0.getQualifiedName());
+        String encodedName = encodedQName + ":" + filename;
 
         try
         {
@@ -1163,6 +1172,15 @@
             rootPath = getAbsoluteFilename().replace(File.separatorChar + filenameNoPath, "");
         else
             rootPath = getAbsoluteFilename().replace(File.separatorChar + packagePath + File.separatorChar + filenameNoPath, "");
+        if (asProject instanceof RoyaleProject)
+        {
+        	String swfDebugfileAlias = ((RoyaleProject)asProject).getSwfDebugfileAlias();
+        	if (swfDebugfileAlias != null)
+        	{
+        		rootPath = swfDebugfileAlias;
+        		packagePath = packagePath.replace('\\', '/');
+        	}
+        }
 
         String encodedPath = rootPath + ';' + packagePath + ';' + getFilenameNoPath();
 
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/units/FXGCompilationUnit.java b/compiler/src/main/java/org/apache/royale/compiler/internal/units/FXGCompilationUnit.java
index 1d62143..406f6fa 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/units/FXGCompilationUnit.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/units/FXGCompilationUnit.java
@@ -52,6 +52,7 @@
 import org.apache.royale.compiler.internal.parsing.as.ASParser;
 import org.apache.royale.compiler.internal.projects.CompilerProject;
 import org.apache.royale.compiler.internal.projects.DefinitionPriority.BasePriority;
+import org.apache.royale.compiler.internal.projects.RoyaleProject;
 import org.apache.royale.compiler.internal.scopes.ASProjectScope;
 import org.apache.royale.compiler.internal.scopes.FXGFileScope;
 import org.apache.royale.compiler.internal.scopes.PackageScope;
@@ -64,6 +65,7 @@
 import org.apache.royale.compiler.internal.units.requests.SyntaxTreeRequestResult;
 import org.apache.royale.compiler.problems.ICompilerProblem;
 import org.apache.royale.compiler.problems.InternalCompilerProblem2;
+import org.apache.royale.compiler.projects.ICompilerProject;
 import org.apache.royale.compiler.units.requests.IABCBytesRequestResult;
 import org.apache.royale.compiler.units.requests.IFileScopeRequestResult;
 import org.apache.royale.compiler.units.requests.IOutgoingDependenciesRequestResult;
@@ -95,7 +97,16 @@
         public GeneratedSourceFileSpecfication(String name, String content)
         {
             this.reader = new StringReader(content);
-            this.name = FilenameNormalization.normalize(name);
+            String alias = null;
+            ICompilerProject project = FXGCompilationUnit.this.getProject();
+            if (project instanceof RoyaleProject)
+            {
+            	alias = ((RoyaleProject)project).getSwfDebugfileAlias();
+            }
+            if (alias != null)
+            	this.name = alias + "/" + name;
+            else
+            	this.name = FilenameNormalization.normalize(name);
         }
 
         private final StringReader reader;
@@ -124,6 +135,12 @@
         {
             return false;
         }
+
+		@Override
+		public void setLastModified(long fileDate) {
+			// TODO Auto-generated method stub
+			
+		}
     }
 
     public FXGCompilationUnit(CompilerProject project, String path, BasePriority basePriority, String qname)
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/units/SWCCompilationUnit.java b/compiler/src/main/java/org/apache/royale/compiler/internal/units/SWCCompilationUnit.java
index 7a3d1ce..cb09a07 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/units/SWCCompilationUnit.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/units/SWCCompilationUnit.java
@@ -410,6 +410,11 @@
     {
         return swc.isANE();
     }
+
+    public ISWC getSWC()
+    {
+        return swc;
+    }
     
     @Override
     public String getName()
@@ -456,7 +461,21 @@
      */
     protected static String getLinkReportName(ICompilationUnit cu)
     {
-        StringBuilder reportBuilder = new StringBuilder(cu.getAbsoluteFilename());
+    	String absoluteFileName = cu.getAbsoluteFilename();
+    	ICompilerProject project = cu.getProject();
+    	if (project instanceof RoyaleProject)
+    	{
+    		String alias = ((RoyaleProject)project).getSwfDebugfileAlias();
+    		if (alias != null)
+    		{
+    			// clip off path to SWC
+    			int slash = absoluteFileName.lastIndexOf("/");
+    			int backslash = absoluteFileName.lastIndexOf("\\");
+    			int lastSep = slash > backslash ? slash : backslash;
+    			absoluteFileName = absoluteFileName.substring(lastSep + 1);
+    		}
+    	}
+        StringBuilder reportBuilder = new StringBuilder(absoluteFileName);
         reportBuilder.append('(');
         
         ArrayList<String> definitionQnames = new ArrayList<String>(cu.getDefinitionPromises().size());
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/units/requests/SWFTagsRequestResult.java b/compiler/src/main/java/org/apache/royale/compiler/internal/units/requests/SWFTagsRequestResult.java
index 8c83081..376e3ef 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/units/requests/SWFTagsRequestResult.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/units/requests/SWFTagsRequestResult.java
@@ -28,7 +28,6 @@
 import java.util.Map.Entry;
 
 import org.apache.royale.compiler.embedding.IEmbedData;
-import org.apache.royale.compiler.internal.embedding.EmbedData;
 import org.apache.royale.compiler.internal.embedding.transcoders.TranscoderBase;
 import org.apache.royale.compiler.problems.ICompilerProblem;
 import org.apache.royale.compiler.units.requests.ISWFTagsRequestResult;
diff --git a/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractClassCannotBeInstantiatedProblem.java b/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractClassCannotBeInstantiatedProblem.java
new file mode 100644
index 0000000..e9d34d1
--- /dev/null
+++ b/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractClassCannotBeInstantiatedProblem.java
@@ -0,0 +1,42 @@
+/*
+ *
+ *  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.royale.compiler.problems;
+
+import org.apache.royale.compiler.tree.as.IASNode;
+
+/**
+ *  Semantics diagnostic emitted when the method body
+ *  semantic checker detects an attempt to instantiate an abstract class.
+ */
+public final class AbstractClassCannotBeInstantiatedProblem extends SemanticProblem
+{
+    public static final String DESCRIPTION =
+        "Abstract classes cannot be instantiated with the ${NEW} operator.";
+
+    public static final int errorCode = 1156;
+
+    public AbstractClassCannotBeInstantiatedProblem(IASNode site)
+    {
+        super(site);
+    }
+    
+    // Prevent these from being localized.
+    public final String NEW = "new";
+}
diff --git a/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractMethodWithBodyProblem.java b/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractMethodWithBodyProblem.java
new file mode 100644
index 0000000..e847e6b
--- /dev/null
+++ b/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractMethodWithBodyProblem.java
@@ -0,0 +1,41 @@
+/*
+ *
+ *  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.royale.compiler.problems;
+
+import org.apache.royale.compiler.tree.as.IASNode;
+
+/**
+ * Diagnostic emitted when an abstract method has a body
+ */
+public final class AbstractMethodWithBodyProblem extends SemanticProblem
+{
+    public static final String DESCRIPTION =
+        "Method marked ${ABSTRACT} must not have a body.";
+
+    public static final int errorCode = 1125;
+
+    public AbstractMethodWithBodyProblem(IASNode site)
+    {
+        super(site);
+    }
+    
+    // Prevent these from being localized.
+    public final String ABSTRACT = "abstract";
+}
diff --git a/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractOutsideClassProblem.java b/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractOutsideClassProblem.java
new file mode 100644
index 0000000..4ab44e2
--- /dev/null
+++ b/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractOutsideClassProblem.java
@@ -0,0 +1,43 @@
+/*
+ *
+ *  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.royale.compiler.problems;
+
+import org.apache.royale.compiler.tree.as.IASNode;
+
+/**
+ * Problem generated when 'abstract' is used outside of a class
+ */
+public final class AbstractOutsideClassProblem extends CodegenProblem
+{
+    // TODO ErrorMSG: not specific to methods
+    public static final String DESCRIPTION =
+            "The ${ABSTRACT} attribute can only be used on a ${CLASS} definition or a non-static, non-final method defined on an ${ABSTRACT} ${CLASS}.";
+
+    public static final int errorCode = 1011;
+
+    public AbstractOutsideClassProblem(IASNode site)
+    {
+        super(site);
+    }
+
+    // Prevent these from being localized.
+    public final String ABSTRACT = "abstract";
+    public final String CLASS = "class";
+}
diff --git a/compiler/src/main/java/org/apache/royale/compiler/problems/BadAccessAbstractMethodProblem.java b/compiler/src/main/java/org/apache/royale/compiler/problems/BadAccessAbstractMethodProblem.java
new file mode 100644
index 0000000..edd19cb
--- /dev/null
+++ b/compiler/src/main/java/org/apache/royale/compiler/problems/BadAccessAbstractMethodProblem.java
@@ -0,0 +1,43 @@
+/*
+ *
+ *  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.royale.compiler.problems;
+
+import org.apache.royale.compiler.tree.as.IASNode;
+
+/**
+ * Diagnostic emitted when the code generator detects an abstract method
+ * declared with an invalid access modifier
+ */
+public final class BadAccessAbstractMethodProblem extends SemanticProblem
+{
+    public static final String DESCRIPTION =
+        "Methods that are ${ABSTRACT} cannot be declared ${PRIVATE}.";
+
+    public static final int errorCode = 1157;
+
+    public BadAccessAbstractMethodProblem(IASNode site)
+    {
+        super(site);
+    }
+    
+    // Prevent these from being localized.
+    public final String ABSTRACT = "abstract";
+    public final String PRIVATE = "private";
+}
diff --git a/compiler/src/main/java/org/apache/royale/compiler/problems/ConstructorMustBePublicOrPrivateProblem.java b/compiler/src/main/java/org/apache/royale/compiler/problems/ConstructorMustBePublicOrPrivateProblem.java
new file mode 100644
index 0000000..93e8755
--- /dev/null
+++ b/compiler/src/main/java/org/apache/royale/compiler/problems/ConstructorMustBePublicOrPrivateProblem.java
@@ -0,0 +1,42 @@
+/*
+ *
+ *  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.royale.compiler.problems;
+
+import org.apache.royale.compiler.tree.as.IASNode;
+
+/**
+ * Diagnostic emitted when a constructor is not public or private
+ */
+public final class ConstructorMustBePublicOrPrivateProblem extends CodegenProblem
+{
+    public static final String DESCRIPTION =
+        "A constructor can only be declared ${PUBLIC} or ${PRIVATE}";
+
+    public static final int errorCode = 1153;
+
+    public ConstructorMustBePublicOrPrivateProblem(IASNode site)
+    {
+        super(site);
+    }
+    
+    // Prevent these from being localized.
+    public final String PUBLIC = "public";
+    public final String PRIVATE = "private";
+}
diff --git a/compiler/src/main/java/org/apache/royale/compiler/problems/InaccessibleConstructorReferenceProblem.java b/compiler/src/main/java/org/apache/royale/compiler/problems/InaccessibleConstructorReferenceProblem.java
new file mode 100644
index 0000000..761717a
--- /dev/null
+++ b/compiler/src/main/java/org/apache/royale/compiler/problems/InaccessibleConstructorReferenceProblem.java
@@ -0,0 +1,43 @@
+/*
+ *
+ *  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.royale.compiler.problems;
+
+import org.apache.royale.compiler.tree.as.IASNode;
+
+/**
+ *  Diagnostic emitted when the semantic analyzer detects 
+ *  an attempt to call an inaccessible constructor (e.g., a
+ *  private constructor call outside the class).
+ */
+public final class InaccessibleConstructorReferenceProblem extends StrictSemanticsProblem
+{
+    public static final String DESCRIPTION =
+        "Attempted access of inaccessible constructor through a reference with static type ${className}.";
+
+    public static final int errorCode = 1195;
+
+    public InaccessibleConstructorReferenceProblem(IASNode site, final String className)
+    {
+        super(site);
+        this.className = className;
+    }
+    
+    public final String className;
+}
diff --git a/compiler/src/main/java/org/apache/royale/compiler/problems/TypeParametersWithNonParameterizedTypeProblem.java b/compiler/src/main/java/org/apache/royale/compiler/problems/TypeParametersWithNonParameterizedTypeProblem.java
new file mode 100644
index 0000000..8287171
--- /dev/null
+++ b/compiler/src/main/java/org/apache/royale/compiler/problems/TypeParametersWithNonParameterizedTypeProblem.java
@@ -0,0 +1,38 @@
+/*
+ *
+ *  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.royale.compiler.problems;
+
+import org.apache.royale.compiler.tree.as.IASNode;
+
+/**
+ *  Semantics diagnostic emitted when the method body
+ *  semantic checker detects an attempt to add type parameters to a
+ *  non-parameterized type.
+ */
+public final class TypeParametersWithNonParameterizedTypeProblem extends SemanticProblem
+{
+    public static final String DESCRIPTION =
+        "Type parameters with a non-parameterized type.";
+
+    public TypeParametersWithNonParameterizedTypeProblem(IASNode site)
+    {
+        super(site);
+    }
+}
diff --git a/compiler/src/main/java/org/apache/royale/compiler/problems/UnimplementedAbstractMethodProblem.java b/compiler/src/main/java/org/apache/royale/compiler/problems/UnimplementedAbstractMethodProblem.java
new file mode 100644
index 0000000..332cd42
--- /dev/null
+++ b/compiler/src/main/java/org/apache/royale/compiler/problems/UnimplementedAbstractMethodProblem.java
@@ -0,0 +1,50 @@
+/*
+ *
+ *  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.royale.compiler.problems;
+
+import org.apache.royale.compiler.definitions.IDefinition;
+
+/**
+ * Problem generated when a class does not implement an abstract method from one
+ * of its superclasses.
+ */
+public final class UnimplementedAbstractMethodProblem extends CodegenProblem
+{
+    public static final String DESCRIPTION =
+        "Method ${methodName} in ${ABSTRACT} ${CLASS} ${abstractClassName} not implemented by ${CLASS} ${className}";
+
+    public static final int errorCode = 1044;
+
+    public UnimplementedAbstractMethodProblem(IDefinition site, String methodName, String abstractClassName, String className)
+    {
+        super(site);
+        this.methodName = methodName;
+        this.abstractClassName = abstractClassName;
+        this.className = className;
+    }
+    
+    public final String methodName;
+    public final String abstractClassName;
+    public final String className;
+
+    // Prevent these from being localized.
+    public final String ABSTRACT = "abstract";
+    public final String CLASS = "class";
+}
diff --git a/compiler/src/main/java/org/apache/royale/compiler/projects/IRoyaleProject.java b/compiler/src/main/java/org/apache/royale/compiler/projects/IRoyaleProject.java
index c1c206a..f1a63db 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/projects/IRoyaleProject.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/projects/IRoyaleProject.java
@@ -233,4 +233,10 @@
      * List of defined variables so it can be overridden
      */
     Map<String, String> getCompilerDefine(Configuration config);
+    
+    /**
+     * The File for the link report
+     */
+    File getLinkReport(Configuration config);
+
 }
diff --git a/compiler/src/main/java/org/apache/royale/swc/SWCLibrary.java b/compiler/src/main/java/org/apache/royale/swc/SWCLibrary.java
index 2a708d2..c8a49af 100644
--- a/compiler/src/main/java/org/apache/royale/swc/SWCLibrary.java
+++ b/compiler/src/main/java/org/apache/royale/swc/SWCLibrary.java
@@ -33,7 +33,6 @@
 import org.apache.royale.swc.io.SWCReader;
 import org.apache.royale.swf.ISWF;
 import org.apache.royale.swf.io.ISWFReader;
-import org.apache.royale.swf.io.SWFReader;
 
 /**
  * Implementation of library model in a SWC.
diff --git a/compiler/src/main/java/org/apache/royale/swc/io/SWCWriter.java b/compiler/src/main/java/org/apache/royale/swc/io/SWCWriter.java
index 55ceff8..c64e6ad 100644
--- a/compiler/src/main/java/org/apache/royale/swc/io/SWCWriter.java
+++ b/compiler/src/main/java/org/apache/royale/swc/io/SWCWriter.java
@@ -20,6 +20,7 @@
 package org.apache.royale.swc.io;
 
 import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
@@ -28,12 +29,15 @@
 import java.io.OutputStreamWriter;
 import java.io.Writer;
 import java.security.DigestOutputStream;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.zip.CRC32;
 import java.util.zip.Deflater;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
 import org.apache.commons.io.IOUtils;
-
+import org.apache.royale.compiler.filespecs.FileSpecification;
 import org.apache.royale.swc.ISWC;
 import org.apache.royale.swc.ISWCFileEntry;
 import org.apache.royale.swc.ISWCLibrary;
@@ -54,9 +58,9 @@
      * 
      * @param filename path to write the file to.
      */
-    public SWCWriter(final String filename) throws FileNotFoundException
+    public SWCWriter(final String filename, String swcDate, String swcDateFormat) throws FileNotFoundException
     {
-        this(filename, true, true, false, SizeReportWritingSWFWriter.getSWFWriterFactory(null));
+        this(filename, true, true, false, swcDate, swcDateFormat, SizeReportWritingSWFWriter.getSWFWriterFactory(null));
     }
     
     /**
@@ -71,6 +75,7 @@
             boolean compressLibrarySWF,
             boolean enableDebug,
             boolean enableTelemetry,
+            String metadataDate, String metadataFormat,
             ISWFWriterFactory swfWriterFactory) throws FileNotFoundException
     {
         super(compressLibrarySWF, enableDebug, enableTelemetry, swfWriterFactory);
@@ -80,6 +85,26 @@
         File outputDirectory = new File(outputFile.getAbsoluteFile().getParent());
         outputDirectory.mkdirs();
         
+    	if (metadataDate != null)
+    	{
+    		// strip off timezone.  Zip format doesn't store timezone
+    		// and the goal is to have the same date and time regardless
+    		// of which timezone the build machine is using.
+    		int c = metadataDate.lastIndexOf(" ");
+    		metadataDate = metadataDate.substring(0,  c);
+    		c = metadataFormat.lastIndexOf(" ");
+    		metadataFormat = metadataFormat.substring(0, c);
+    		try {
+    			SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
+    			fileDate = sdf.parse(metadataDate).getTime();
+    		} catch (ParseException e) {
+    			// TODO Auto-generated catch block
+    			e.printStackTrace();
+    		} catch (IllegalArgumentException e1) {
+    			e1.printStackTrace();
+    		}
+    	}
+    	
         zipOutputStream = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(filename)));
         zipOutputStream.setLevel(Deflater.NO_COMPRESSION);
     }
@@ -88,14 +113,30 @@
      * Target SWC output stream.
      */
     private final ZipOutputStream zipOutputStream;
+    
+    private long fileDate = System.currentTimeMillis();
 
     @Override
     void writeCatalog(final ISWC swc) throws IOException
     {
-        zipOutputStream.putNextEntry(new ZipEntry(CATALOG_XML));
-        final Writer catalogXMLWriter = new OutputStreamWriter(zipOutputStream);
+    	ZipEntry ze = new ZipEntry(CATALOG_XML);
+    	ze.setTime(fileDate);
+    	ze.setMethod(ZipEntry.STORED);
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        final Writer catalogXMLWriter = new OutputStreamWriter(baos);
         writeCatalogXML(swc, catalogXMLWriter);
         catalogXMLWriter.flush();
+        ze.setSize(baos.size());
+        ze.setCompressedSize(baos.size());
+        CRC32 crc = new CRC32();
+        crc.reset();
+        crc.update(baos.toByteArray());
+        ze.setCrc(crc.getValue());
+        zipOutputStream.putNextEntry(ze);
+        
+        baos.writeTo(zipOutputStream);
+        
         zipOutputStream.closeEntry();
     }
 
@@ -107,14 +148,26 @@
         assert swf != null : "Expect SWF model";
         assert path != null : "Expect SWF path";
 
-        zipOutputStream.putNextEntry(new ZipEntry(path));
-
-        final DigestOutputStream digestStream = getDigestOutputStream(library, zipOutputStream);
-
+        ZipEntry ze = new ZipEntry(path);
+    	ze.setTime(fileDate);
+    	ze.setMethod(ZipEntry.STORED);
+    	
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ISWFWriter swfWriter = swfWriterFactory.createSWFWriter(swf,
                 getLibrarySWFCompression(), enableDebug, enableTelemetry);
-        swfWriter.writeTo(digestStream != null ? digestStream : zipOutputStream);
+        swfWriter.writeTo(baos);
         swfWriter.close();
+        ze.setSize(baos.size());
+        ze.setCompressedSize(baos.size());
+        CRC32 crc = new CRC32();
+        crc.reset();
+        crc.update(baos.toByteArray());
+        ze.setCrc(crc.getValue());
+        zipOutputStream.putNextEntry(ze);        
+
+        final DigestOutputStream digestStream = getDigestOutputStream(library, zipOutputStream);
+        baos.writeTo(digestStream != null ? digestStream : zipOutputStream);
+        
         zipOutputStream.closeEntry();
         
         if (digestStream != null) {
@@ -125,10 +178,35 @@
     @Override
     void writeFile(final ISWCFileEntry fileEntry) throws IOException
     {
-        zipOutputStream.putNextEntry(new ZipEntry(fileEntry.getPath()));
+    	ZipEntry ze = new ZipEntry(fileEntry.getPath());
+    	ze.setTime(fileDate);        
+    	ze.setMethod(ZipEntry.STORED);
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
         final InputStream fileInputStream = fileEntry.createInputStream();
-        IOUtils.copy(fileInputStream, zipOutputStream);
-        fileInputStream.close();
+        String name = fileEntry.getPath();
+        if (name.endsWith(".css")) // add other text files here
+        {
+        	FileSpecification.NoCRLFInputStream filteredInputStream = 
+        			new FileSpecification.NoCRLFInputStream(fileInputStream);
+        	IOUtils.copy(filteredInputStream, baos);
+        	filteredInputStream.close();
+        }
+        else
+        {
+        	IOUtils.copy(fileInputStream, baos);
+        	fileInputStream.close();
+        }
+        
+        ze.setSize(baos.size());
+        ze.setCompressedSize(baos.size());
+        CRC32 crc = new CRC32();
+        crc.reset();
+        crc.update(baos.toByteArray());
+        ze.setCrc(crc.getValue());
+        zipOutputStream.putNextEntry(ze);
+        
+        baos.writeTo(zipOutputStream);
         zipOutputStream.closeEntry();
     }
 
diff --git a/compiler/src/main/java/org/apache/royale/swf/io/SWFDump.java b/compiler/src/main/java/org/apache/royale/swf/io/SWFDump.java
index 4c35786..5f5fdc7 100644
--- a/compiler/src/main/java/org/apache/royale/swf/io/SWFDump.java
+++ b/compiler/src/main/java/org/apache/royale/swf/io/SWFDump.java
@@ -1394,7 +1394,7 @@
                 if (styleChange.isStateLineStyle())
                 {
                     out.print("lineStyle=\"" +
-                              (styles.getFillStyles().indexOf(styleChange.getLinestyle()) + 1) + "\" ");
+                              (styles.getLineStyles().indexOf(styleChange.getLinestyle()) + 1) + "\" ");
                 }
                 if (styleChange.isStateNewStyles())
                 {
diff --git a/compiler/src/main/java/org/apache/royale/swf/io/SWFWriter.java b/compiler/src/main/java/org/apache/royale/swf/io/SWFWriter.java
index 1747e7d..a5cbc3f 100644
--- a/compiler/src/main/java/org/apache/royale/swf/io/SWFWriter.java
+++ b/compiler/src/main/java/org/apache/royale/swf/io/SWFWriter.java
@@ -1465,7 +1465,8 @@
             writeTag(extraTag);
     }
 
-    private boolean writeRawTag(RawTag tag)
+    @SuppressWarnings("incomplete-switch")
+	private boolean writeRawTag(RawTag tag)
     {
         boolean skipTag = false;
         // if writing out an AS3 swf, there are a number of
diff --git a/compiler/src/main/java/org/apache/royale/swf/io/SizeReportWritingSWFWriter.java b/compiler/src/main/java/org/apache/royale/swf/io/SizeReportWritingSWFWriter.java
index 610f0af..545070b 100644
--- a/compiler/src/main/java/org/apache/royale/swf/io/SizeReportWritingSWFWriter.java
+++ b/compiler/src/main/java/org/apache/royale/swf/io/SizeReportWritingSWFWriter.java
@@ -138,7 +138,8 @@
         writeSizeReport();
     }
 
-    @Override
+    @SuppressWarnings("incomplete-switch")
+	@Override
     protected void finishTag(ITag tag, IOutputBitStream tagData, IOutputBitStream out)
     {
         int startPos = out.size();
diff --git a/compiler/src/main/jflex/org/apache/royale/compiler/internal/parsing/mxml/RawMXMLTokenizer.lex b/compiler/src/main/jflex/org/apache/royale/compiler/internal/parsing/mxml/RawMXMLTokenizer.lex
index 7dfd516..be7802b 100644
--- a/compiler/src/main/jflex/org/apache/royale/compiler/internal/parsing/mxml/RawMXMLTokenizer.lex
+++ b/compiler/src/main/jflex/org/apache/royale/compiler/internal/parsing/mxml/RawMXMLTokenizer.lex
@@ -377,8 +377,7 @@
 // or a TOKEN_EMPTY_TAG_END token (for />) before returning to the
 // initial state.
 
-
-<MARKUP> "xmlns"?(":"{ID_FOLLOW}*)?
+<MARKUP> "xmlns"(":"{ID_FOLLOW}*)?
 {
 	return buildToken(TOKEN_XMLNS);
 }
diff --git a/compiler/src/main/resources/downloads.xml b/compiler/src/main/resources/downloads.xml
index ce7528c..b3195a2 100644
--- a/compiler/src/main/resources/downloads.xml
+++ b/compiler/src/main/resources/downloads.xml
@@ -29,7 +29,7 @@
               antlr (3) - BSD
               commons-cli (1.2) - Apache 2.0
               commons-io (2.0.1) - Apache 2.0
-              guava (15.0) - Apache 2.0
+              guava (25.1) - Apache 2.0
               JBurg (1.10.2) - CPL 1.0
               lzma-sdk (9.2) - Public Domain
   -->
@@ -131,13 +131,13 @@
 
     <!--  guava -->
     <property name="guava.name" value="guava"/>
-    <property name="guava.version" value="20.0"/>
+    <property name="guava.version" value="25.1-jre"/>
     <antcall target="download-dependency">
       <param name="name" value="${guava.name}"/>
       <param name="src.server" value="${maven.search.url}"/>
       <param name="src.folder" value="com/google/guava/guava/${guava.version}"/>
       <param name="src.filename" value="guava-${guava.version}.jar"/>
-      <param name="src.checksum" value="f32a8a2524620dbecc9f6bf6a20c293f"/>
+      <param name="src.checksum" value="da3838847d109ac435f0d3ed4ae1c794"/>
       <param name="dest.folder" value=""/>
       <param name="dest.filename" value="${guava.name}.jar"/>
       <param name="license.use.apache" value="true"/>
@@ -166,7 +166,7 @@
     <property name="jflex.name" value="jflex"/>
     <property name="jflex.version" value="1.6.0"/>
     <!-- property name="jflex.version" value="1.5.1"/ -->
-    <property name="jflex.server" value="http://jflex.de"/>
+    <property name="jflex.server" value="https://jflex.de"/>
     <property name="jflex.folder" value="."/>
     <property name="jflex.filename" value="${jflex.name}-${jflex.version}.tar.gz"/>
     <property name="jflex.md5" value="df8cc9ca50b549bf705bd23479c100dc"/>
@@ -193,10 +193,10 @@
     <!--  lzma -->
     <property name="lzma.name" value="lzma"/>
     <property name="lzma.version" value="9.20"/>
-    <property name="lzma.server" value="http://www.java2s.com"/>
-    <property name="lzma.folder" value="Code/JarDownload/lzma"/>
-    <property name="lzma.filename" value="${lzma.name}-${lzma.version}.jar.zip"/>
-    <property name="lzma.md5" value="d5f7343bbd03bf1c4a4806b372cc5354"/>
+    <property name="lzma.server" value="${maven.search.url}"/>
+    <property name="lzma.folder" value="org/b1/pack/lzma-sdk-4j/9.22.0"/>
+    <property name="lzma.filename" value="lzma-sdk-4j-9.22.0.jar"/>
+    <property name="lzma.md5" value="15fe7f01f4a37ea0f93e6ff5736406fd"/>
     <antcall target="download-dependency">
       <param name="name" value="${lzma.name}-sdk"/>
       <param name="version" value="${lzma.version}"/>
diff --git a/compiler/src/test/downloads.xml b/compiler/src/test/downloads.xml
index ba638a1..a9e0943 100644
--- a/compiler/src/test/downloads.xml
+++ b/compiler/src/test/downloads.xml
@@ -130,7 +130,7 @@
     <target name="junit-download-jar" depends="junit-jar-check" unless="junit.jar.exists"
             description="Downloads the JUnit jar.">
         <antcall target="download-jar">
-            <param name="srcUrl" value="http://search.maven.org/remotecontent?filepath=junit/junit/4.10"/>
+            <param name="srcUrl" value="https://search.maven.org/remotecontent?filepath=junit/junit/4.10"/>
             <param name="srcJarFile" value="junit-4.10.jar"/>
             <param name="destDir" value="${external.lib.dir}"/>
             <param name="destJarFile" value="junit-4.10.jar"/>
diff --git a/compiler/src/test/java/as/ASAbstractClassTests.java b/compiler/src/test/java/as/ASAbstractClassTests.java
new file mode 100644
index 0000000..d98c122
--- /dev/null
+++ b/compiler/src/test/java/as/ASAbstractClassTests.java
@@ -0,0 +1,1193 @@
+/*
+ *
+ *  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 as;
+
+import java.io.File;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ASAbstractClassTests extends ASFeatureTestsBase
+{
+    @Test
+    public void testAbstractNotAllowedOnClassError_withAllowAbstractClassesDisabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+            //error because abstract classes have not been enabled
+            "abstract class A {",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+            "-allow-abstract-classes=false"
+        };
+        compileAndExpectErrors(source, false,false,false, options,"'abstract' is not allowed here\n");
+    }
+    
+    @Test
+    public void testAbstractNotAllowedOnInterfaceError_withAllowAbstractClassesDisabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+            //error because abstract classes have not been enabled
+            "abstract interface A {",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+            "-allow-abstract-classes=false"
+        };
+        compileAndExpectErrors(source, false,false,false, options,"'abstract' is not allowed here\n");
+    }
+
+    @Test
+    public void testAbstractNotAllowedOnClassMethodError_withAllowAbstractClassesDisabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"class A {",
+					//error because abstract classes have not been enabled
+					"public abstract function a():void",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=false"
+        };
+        compileAndExpectErrors(source, false,false,false, options,"'abstract' is not allowed here\nFunction does not have a body.\n");
+	}
+
+    @Test
+    public void testAbstractNotAllowedOnInterfaceMethodError_withAllowAbstractClassesDisabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"interface A {",
+					//error because abstract classes have not been enabled
+					"abstract function a():void",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=false"
+        };
+        compileAndExpectErrors(source, false,false,false, options,"'abstract' is not allowed here\n");
+	}
+
+	@Test
+    public void testAbstractNotAllowedOnStaticMethodError_withAllowAbstractClassesDisabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"class A {",
+					//error because abstract classes have not been enabled
+					"public static abstract function a():void",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=false"
+        };
+        compileAndExpectErrors(source, false,false,false, options,"'abstract' is not allowed here\nFunction does not have a body.\n");
+	}
+
+	@Test
+    public void testAbstractNotAllowedOnGetterError_withAllowAbstractClassesDisabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"class A {",
+					//error because abstract classes have not been enabled
+					"public abstract function get a():Object;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=false"
+        };
+        compileAndExpectErrors(source, false,false,false, options,"'abstract' is not allowed here\nFunction does not have a body.\nFunction does not return a value.\n");
+	}
+
+	@Test
+    public void testAbstractNotAllowedOnSetterError_withAllowAbstractClassesDisabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"class A {",
+					//error because abstract classes have not been enabled
+					"public abstract function set a(value:Object):void;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=false"
+        };
+        compileAndExpectErrors(source, false,false,false, options,"'abstract' is not allowed here\nFunction does not have a body.\n");
+	}
+
+	@Test
+    public void testAbstractNotAllowedOnVariableError_withAllowAbstractClassesDisabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"class A {",
+					//error because abstract classes have not been enabled
+					"public abstract var a:Object;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=false"
+        };
+        compileAndExpectErrors(source, false,false,false, options,"'abstract' is not allowed here\n");
+	}
+
+	@Test
+    public void testAbstractNotAllowedOnStaticVariableError_withAllowAbstractClassesDisabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"class A {",
+					//error because abstract classes have not been enabled
+					"public static abstract var a:Object;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=false"
+        };
+        compileAndExpectErrors(source, false,false,false, options,"'abstract' is not allowed here\n");
+	}
+
+    @Test
+    public void testAbstractNotAllowedOnInterfaceGetterError_withAllowAbstractClassesDisabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"interface A {",
+					//error because abstract classes have not been enabled
+					"abstract function get a():Object;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=false"
+        };
+        compileAndExpectErrors(source, false,false,false, options,"'abstract' is not allowed here\n");
+	}
+
+    @Test
+    public void testAbstractNotAllowedOnInterfaceSetterError_withAllowAbstractClassesDisabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"interface A {",
+					//error because abstract classes have not been enabled
+					"abstract function set a(value:Object):void;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=false"
+        };
+        compileAndExpectErrors(source, false,false,false, options,"'abstract' is not allowed here\n");
+	}
+
+	@Test
+    public void testAbstractClassNoErrors_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+        File tempASFile = generateTempFile(source);
+        String result = compile(tempASFile, source, false,false,false, options, true);
+        Assert.assertEquals("", result);
+    }
+
+	@Test
+    public void testAbstractMethodOnClassNoErrors_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"public abstract function a():void;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		File tempASFile = generateTempFile(source);
+		String result = compile(tempASFile, source, false,false,false, options, true);
+		Assert.assertEquals("", result);
+	}
+
+	@Test
+    public void testAbstractMethodWithParametersAndReturnOnClassNoErrors_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"public abstract function a(arg0:String, arg1:Number):Boolean;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		File tempASFile = generateTempFile(source);
+		String result = compile(tempASFile, source, false,false,false, options, true);
+		Assert.assertEquals("", result);
+	}
+
+	@Test
+    public void testAbstractMethodOnInterfaceError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"interface A {",
+					"abstract function a():void;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+        compileAndExpectErrors(source, false,false,false, options, "The abstract attribute can only be used on a class definition or a non-static, non-final method defined on an abstract class.\n");
+	}
+
+	@Test
+    public void testAbstractGetterOnInterfaceError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"interface A {",
+					"abstract function get a():Object;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+        compileAndExpectErrors(source, false,false,false, options, "The abstract attribute can only be used on a class definition or a non-static, non-final method defined on an abstract class.\n");
+	}
+
+	@Test
+    public void testAbstractSetterOnInterfaceError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"interface A {",
+					"abstract function set a(value:Object):void;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+        compileAndExpectErrors(source, false,false,false, options, "The abstract attribute can only be used on a class definition or a non-static, non-final method defined on an abstract class.\n");
+	}
+
+	@Test
+    public void testAbstractProtectedMethodNoErrors_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"protected abstract function a():void;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		File tempASFile = generateTempFile(source);
+		String result = compile(tempASFile, source, false,false,false, options, true);
+		Assert.assertEquals("", result);
+	}
+
+	@Test
+    public void testAbstractInternalMethodNoErrors_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"internal abstract function a():void;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		File tempASFile = generateTempFile(source);
+		String result = compile(tempASFile, source, false,false,false, options, true);
+		Assert.assertEquals("", result);
+	}
+
+	@Test
+    public void testAbstractPrivateMethodError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"private abstract function a():void;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+        compileAndExpectErrors(source, false,false,false, options, "Methods that are abstract cannot be declared private.\n");
+	}
+
+	@Test
+    public void testAbstractFinalClassError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract final class A {",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+        compileAndExpectErrors(source, false,false,false, options, "The abstract attribute can only be used on a class definition or a non-static, non-final method defined on an abstract class.\n");
+	}
+
+	@Test
+    public void testAbstractFinalMethodError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"public final abstract function a():void;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+        compileAndExpectErrors(source, false,false,false, options, "The abstract attribute can only be used on a class definition or a non-static, non-final method defined on an abstract class.\nFunction does not have a body.\n");
+	}
+
+	@Test
+    public void testAbstractMethodNotInAbstractClassError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"class A {",
+					//error because an abstract method may only be defined on an
+					//abstract class
+					"public abstract function a():void;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		compileAndExpectErrors(source, false,false,false, options, "The abstract attribute can only be used on a class definition or a non-static, non-final method defined on an abstract class.\nFunction does not have a body.\n");
+	}
+
+	@Test
+    public void testAbstractStaticMethodError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					//error because a static function cannot be abstract
+					"public static abstract function a():void;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		compileAndExpectErrors(source, false,false,false, options, "The abstract attribute can only be used on a class definition or a non-static, non-final method defined on an abstract class.\nFunction does not have a body.\n");
+	}
+
+	@Test
+    public void testAbstractGetterError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					//error because a getter cannot be abstract
+					"public abstract function get a():Object;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		compileAndExpectErrors(source, false,false,false, options, "The abstract attribute can only be used on a class definition or a non-static, non-final method defined on an abstract class.\nFunction does not have a body.\nFunction does not return a value.\n");
+	}
+
+	@Test
+    public void testAbstractSetterError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					//error because a setter cannot be abstract
+					"public abstract function set a(value:Object):void;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		compileAndExpectErrors(source, false,false,false, options, "The abstract attribute can only be used on a class definition or a non-static, non-final method defined on an abstract class.\nFunction does not have a body.\n");
+	}
+
+	@Test
+    public void testAbstractVariableError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					//error because a variable cannot be abstract
+					"public abstract var a:Object;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		compileAndExpectErrors(source, false,false,false, options, "The abstract attribute can only be used on a class definition or a non-static, non-final method defined on an abstract class.\n");
+	}
+
+	@Test
+    public void testAbstractStaticVariableError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					//error because a static variable cannot be abstract
+					"public static abstract var a:Object;",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		compileAndExpectErrors(source, false,false,false, options, "The abstract attribute can only be used on a class definition or a non-static, non-final method defined on an abstract class.\n");
+	}
+
+	@Test
+    public void testAbstractMethodBodyError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					//error because an abstract method has a body
+					"public abstract function a():void {}",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		compileAndExpectErrors(source, false,false,false, options, "Method marked abstract must not have a body.\n");
+	}
+
+	@Test
+    public void testAbstractClassNewOperatorError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+					//error because the class is abstract and cannot be
+					//instantiated with new
+					"var obj:A = new A();",
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		compileAndExpectErrors(source, false,false,false, options, "Abstract classes cannot be instantiated with the new operator.\n");
+	}
+
+	@Test
+    public void testConcreteClassExtendsAbstractNewOperatorNoErrors_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+					"var obj:A = new B();",
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"}",
+					"class B extends A {",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		File tempASFile = generateTempFile(source);
+		String result = compile(tempASFile, source, false,false,false, options, true);
+		Assert.assertEquals("", result);
+	}
+
+	@Test
+    public void testAbstractClassSuperError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"public abstract function a():void;",
+					"}",
+					"class B extends A {",
+					"override public function a():void {",
+					//error because the the super method is abstract
+					"super.a();",
+					"};",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		compileAndExpectErrors(source, false,false,false, options, "Call to a possibly undefined method a.\n");
+	}
+
+	@Test
+    public void testAbstractClassNotImplementedError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"public abstract function a():void;",
+					"}",
+					"class B extends A {",
+					//error because we did not implement the abstract method in
+					//a concrete subclass
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		compileAndExpectErrors(source, false,false,false, options, "Method a in abstract class A not implemented by class B\n");
+	}
+
+	@Test
+    public void testAbstractClassNotImplementedErrorOneTimeForTwoConcreteSubclasses_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"public abstract function a():void;",
+					"}",
+                    "class B extends A {",
+					//error because we did not implement the abstract method in
+					//a concrete subclass
+                    "}",
+                    "class C extends B {",
+                    //no duplicate error here!
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		compileAndExpectErrors(source, false,false,false, options, "Method a in abstract class A not implemented by class B\n");
+	}
+
+	@Test
+    public void testAbstractClassMissingOverrideError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"public abstract function a():void;",
+					"}",
+					"class B extends A {",
+					//error because we did not use the override keyword
+					"public function a():void {}",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		compileAndExpectErrors(source, false,false,false, options, "Overriding a function that is not marked for override\n");
+	}
+
+	@Test
+    public void testAbstractClassExtendsAbstractWithoutImplementingNoError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"public abstract function a():void;",
+					"}",
+					"abstract class B extends A {",
+					//we don't want an error for unimplemented methods because
+					//this class is also abstract
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		File tempASFile = generateTempFile(source);
+		String result = compile(tempASFile, source, false,false,false, options, true);
+		Assert.assertEquals("", result);
+	}
+
+	@Test
+    public void testConcreteClassExtendsAbstractExtendsAbstractNotImplementedError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"public abstract function a():void;",
+					"}",
+					"abstract class B extends A {",
+					//we don't want an error for unimplemented methods because
+					//this class is also abstract
+					"}",
+					"class C extends B {",
+					//but we do want an error here for unimplemented methods
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+        compileAndExpectErrors(source, false,false,false, options, "Method a in abstract class A not implemented by class C\n");
+	}
+
+	@Test
+    public void testConcreteClassExtendsAbstractExtendsAbstractMultipleNotImplementedErrors_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"public abstract function a():void;",
+					"}",
+					"abstract class B extends A {",
+					"public abstract function b():void;",
+					"}",
+					"class C extends B {",
+					//mulitple errors because more than one method is not implemented
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+        compileAndExpectErrors(source, false,false,false, options, "Method b in abstract class B not implemented by class C\nMethod a in abstract class A not implemented by class C\n");
+	}
+
+	@Test
+    public void testAbstractClassExtendsAbstractAndImplementsNoError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"public abstract function a():void;",
+					"}",
+					"abstract class B extends A {",
+					//it's okay for an abstract subclass to implement any
+					//abstract methods from the superclass
+					"override public function a():void {}",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		File tempASFile = generateTempFile(source);
+		String result = compile(tempASFile, source, false,false,false, options, true);
+		Assert.assertEquals("", result);
+	}
+
+	@Test
+    public void testConcreteClassExtendsAbstractNoError_withAllowAbstractClassesEnabled()
+    {
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+					"abstract class A {",
+					"public abstract function a():void;",
+					"}",
+					"class B extends A {",
+					//no errors because we've implemented all of the methods
+					//that are abstract
+					"override public function a():void {}",
+					"}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+
+        String[] options = new String[]
+        {
+					"-allow-abstract-classes=true"
+        };
+		File tempASFile = generateTempFile(source);
+		String result = compile(tempASFile, source, false,false,false, options, true);
+		Assert.assertEquals("", result);
+	}
+}
\ No newline at end of file
diff --git a/compiler/src/test/java/as/ASFeatureTestsBase.java b/compiler/src/test/java/as/ASFeatureTestsBase.java
index 9a5cf71..0b2c597 100644
--- a/compiler/src/test/java/as/ASFeatureTestsBase.java
+++ b/compiler/src/test/java/as/ASFeatureTestsBase.java
@@ -154,7 +154,7 @@
 
         // Check that there were no compilation problems.
         List<ICompilerProblem> problems = mxmlc.getProblems().getProblems();
-        StringBuilder sb = new StringBuilder(checkExitCode ? "Unexpected compilation problems:\n" : "");
+        StringBuilder sb = new StringBuilder(checkExitCode && problems.size() > 0 ? "Unexpected compilation problems:\n" : "");
         for (ICompilerProblem problem : problems)
         {
             sb.append(problem.toString());
diff --git a/compiler/src/test/java/as/ASNamespaceTests.java b/compiler/src/test/java/as/ASNamespaceTests.java
index 0c91d58..40dca57 100644
--- a/compiler/src/test/java/as/ASNamespaceTests.java
+++ b/compiler/src/test/java/as/ASNamespaceTests.java
@@ -41,7 +41,7 @@
         {
         	imports = new String[]
  	        {
- 	            "import chrome.app;",
+ 	            "import Intl.Collator;",
  	        };        	
         }
         String[] testCode;
@@ -60,10 +60,10 @@
         else
         {
             testCode = new String[]{
-                	"var foo:app = new app();",
-                	"var bar:chrome.app = new chrome.app();",
-                	"var b1:Boolean = bar is app;",
-                	"var b2:Boolean = foo is chrome.app;",
+                	"var foo:Collator = new Collator();",
+                	"var bar:Intl.Collator = new Intl.Collator();",
+                	"var b1:Boolean = bar is Collator;",
+                	"var b2:Boolean = foo is Intl.Collator;",
                     "assertEqual('package qualifiers', b1, true);",
                     "assertEqual('package qualifiers', b2, true);",
                 };        	
diff --git a/compiler/src/test/java/as/ASPrivateConstructorTests.java b/compiler/src/test/java/as/ASPrivateConstructorTests.java
new file mode 100644
index 0000000..7981155
--- /dev/null
+++ b/compiler/src/test/java/as/ASPrivateConstructorTests.java
@@ -0,0 +1,631 @@
+/*
+ *
+ *  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 as;
+
+import java.io.File;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ASPrivateConstructorTests extends ASFeatureTestsBase
+{
+    @Test
+	public void testConstructorMustBePublicProblem_withPrivateConstructor_andAllowPrivateConstructorsDisabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+			"class A {",
+            //error because private constructors have not been enabled
+			"private function A() {",
+			"}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=false"
+        };
+        compileAndExpectErrors(source, false, false, false, options, "A constructor can only be declared public\n");
+	}
+
+    @Test
+	public void testConstructorMustBePublicProblem_withProtectedConstructor_andAllowPrivateConstructorsDisabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+			"class A {",
+            //error because protected constructors are not allowed
+			"protected function A() {",
+			"}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=false"
+        };
+        compileAndExpectErrors(source, false, false, false, options, "A constructor can only be declared public\n");
+	}
+
+    @Test
+	public void testConstructorMustBePublicProblem_withInternalConstructor_andAllowPrivateConstructorsDisabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+			"class A {",
+            //error because internal constructors are not allowed
+			"internal function A() {",
+			"}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=false"
+        };
+        compileAndExpectErrors(source, false, false, false, options, "A constructor can only be declared public\n");
+	}
+
+    @Test
+	public void testConstructorMustBePublicProblem_withMetadata_andAllowPrivateConstructorsDisabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+			//error because private constructors have not been enabled
+			"[RoyalePrivateConstructor]",
+			"class A {",
+			"public function A() {",
+			"}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=false"
+        };
+        compileAndExpectErrors(source, false, false, false, options, "A constructor can only be declared public\n");
+    }
+
+    @Test
+	public void testConstructorMustBePublicProblemAndInaccessibleConstructorReferenceProblem_withPrivateConstructor_andAllowPrivateConstructorsDisabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+            //no error because the constructor cannot be private
+            "new A()"
+        };
+        String[] extra = new String[]
+        {
+			"class A {",
+            //error because private constructors have not been enabled
+			"private function A() {",
+			"}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=false"
+        };
+        compileAndExpectErrors(source, false, false, false, options, "A constructor can only be declared public\n");
+	}
+
+    @Test
+	public void testConstructorMustBePublicProblemAndInaccessibleConstructorReferenceProblem_withMetadata_andAllowPrivateConstructorsDisabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+            //no error because the constructor cannot be private
+            "new A()"
+        };
+        String[] extra = new String[]
+        {
+            "[RoyalePrivateConstructor]",
+			"class A {",
+            //error because private constructors have not been enabled
+			"private function A() {",
+			"}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=false"
+        };
+        compileAndExpectErrors(source, false, false, false, options, "A constructor can only be declared public\n");
+	}
+    
+    @Test
+	public void testNoConstructorMustBePublicOrPrivateProblem_withPrivateConstructor_andAllowPrivateConstructorsEnabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+			"class A {",
+			"private function A() {",
+			"}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=true"
+        };
+        File tempASFile = generateTempFile(source);
+        String result = compile(tempASFile, source, false, false, false, options, true);
+        Assert.assertEquals("", result);
+	}
+
+    @Test
+	public void testConstructorMustBePublicOrPrivateProblem_withProtectedConstructor_andAllowPrivateConstructorsEnabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+			"class A {",
+            //error because protected constructors are not allowed
+			"protected function A() {",
+			"}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=true"
+        };
+        compileAndExpectErrors(source, false, false, false, options, "A constructor can only be declared public or private\n");
+	}
+
+    @Test
+	public void testConstructorMustBePublicOrPrivateProblem_withInternalConstructor_andAllowPrivateConstructorsEnabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+			"class A {",
+            //error because internal constructors are not allowed
+			"internal function A() {",
+			"}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=true"
+        };
+        compileAndExpectErrors(source, false, false, false, options, "A constructor can only be declared public or private\n");
+	}
+
+    @Test
+	public void testNoConstructorMustBePublicOrPrivateProblem_withMetadata_andAllowPrivateConstructorsEnabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+			//error because private constructors have not been enabled
+			"[RoyalePrivateConstructor]",
+			"class A {",
+			"public function A() {",
+			"}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=true"
+        };
+        File tempASFile = generateTempFile(source);
+        String result = compile(tempASFile, source, false, false, false, options, true);
+        Assert.assertEquals("", result);
+    }
+
+    @Test
+	public void testInaccessibleConstructorReferenceProblem_withPrivateConstructor_andAllowPrivateConstructorsEnabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+            //error because the constructor is private
+            "new A()"
+        };
+        String[] extra = new String[]
+        {
+			"class A {",
+			"private function A() {",
+			"}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=true"
+        };
+        compileAndExpectErrors(source, false, false, false, options, "Attempted access of inaccessible constructor through a reference with static type A.\n");
+	}
+
+    @Test
+	public void testInaccessibleConstructorReferenceProblem_withMetadata_andAllowPrivateConstructorsEnabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+            //error because the constructor is private
+            "new A()"
+        };
+        String[] extra = new String[]
+        {
+			"[RoyalePrivateConstructor]",
+			"class A {",
+			"private function A() {",
+			"}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=true"
+        };
+        compileAndExpectErrors(source, false, false, false, options, "Attempted access of inaccessible constructor through a reference with static type A.\n");
+	}
+
+    @Test
+	public void testInaccessibleConstructorReferenceProblem_withPrivateConstructor_inFilePrivateArea_andAllowPrivateConstructorsEnabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+			"class A {",
+			"private function A() {",
+			"}",
+            "}",
+            //error because the constructor is private
+            "new A()"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=true"
+        };
+        compileAndExpectErrors(source, false, false, false, options, "Attempted access of inaccessible constructor through a reference with static type A.\n");
+	}
+
+    @Test
+	public void testInaccessibleConstructorReferenceProblem_withMetadata_inFilePrivateArea_andAllowPrivateConstructorsEnabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+			"[RoyalePrivateConstructor]",
+			"class A {",
+			"private function A() {",
+			"}",
+            "}",
+            //error because the constructor is private
+            "new A()"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=true"
+        };
+        compileAndExpectErrors(source, false, false, false, options, "Attempted access of inaccessible constructor through a reference with static type A.\n");
+	}
+
+    @Test
+	public void testNoInaccessibleConstructorReferenceProblem_withPrivateConstructor_inMethodOfSameClass_andAllowPrivateConstructorsEnabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+            "class A {",
+			"private function A() {",
+			"}",
+            "public function method():Object {",
+            "return new A()",
+            "}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=true"
+        };
+        File tempASFile = generateTempFile(source);
+        String result = compile(tempASFile, source, false, false, false, options, true);
+        Assert.assertEquals("", result);
+	}
+
+    @Test
+	public void testNoInaccessibleConstructorReferenceProblem_withMetadata_inMethodOfSameClass_andAllowPrivateConstructorsEnabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+            "[RoyalePrivateConstructor]",
+            "class A {",
+			"private function A() {",
+			"}",
+            "public function method():Object {",
+            "return new A()",
+            "}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=true"
+        };
+        File tempASFile = generateTempFile(source);
+        String result = compile(tempASFile, source, false, false, false, options, true);
+        Assert.assertEquals("", result);
+	}
+
+    @Test
+	public void testNoInaccessibleConstructorReferenceProblem_withPrivateConstructor_inStaticMethodOfSameClass_andAllowPrivateConstructorsEnabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+            "class A {",
+			"private function A() {",
+			"}",
+            "public static function method():Object {",
+            "return new A()",
+            "}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=true"
+        };
+        File tempASFile = generateTempFile(source);
+        String result = compile(tempASFile, source, false, false, false, options, true);
+        Assert.assertEquals("", result);
+	}
+
+    @Test
+	public void testNoInaccessibleConstructorReferenceProblem_withMetadata_inStaticMethodOfSameClass_andAllowPrivateConstructorsEnabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+            "[RoyalePrivateConstructor]",
+            "class A {",
+			"private function A() {",
+			"}",
+            "public static function method():Object {",
+            "return new A()",
+            "}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=true"
+        };
+        File tempASFile = generateTempFile(source);
+        String result = compile(tempASFile, source, false, false, false, options, true);
+        Assert.assertEquals("", result);
+	}
+
+    @Test
+	public void testNoInaccessibleConstructorReferenceProblem_withPrivateConstructor_inGetterOfSameClass_andAllowPrivateConstructorsEnabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+            "class A {",
+			"private function A() {",
+			"}",
+            "public function get getter():Object {",
+            "return new A()",
+            "}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=true"
+        };
+        File tempASFile = generateTempFile(source);
+        String result = compile(tempASFile, source, false, false, false, options, true);
+        Assert.assertEquals("", result);
+	}
+
+    @Test
+	public void testNoInaccessibleConstructorReferenceProblem_withMetadata_inGetterOfSameClass_andAllowPrivateConstructorsEnabled()
+    {
+        String[] imports = new String[]
+        {
+		};
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+        };
+        String[] extra = new String[]
+        {
+            "[RoyalePrivateConstructor]",
+            "class A {",
+			"private function A() {",
+			"}",
+            "public function get getter():Object {",
+            "return new A()",
+            "}",
+            "}"
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        String[] options = new String[]
+        {
+            "-allow-private-constructors=true"
+        };
+        File tempASFile = generateTempFile(source);
+        String result = compile(tempASFile, source, false, false, false, options, true);
+        Assert.assertEquals("", result);
+	}
+}
\ No newline at end of file
diff --git a/compiler/src/test/java/mxml/tags/MXMLFeatureTestsBase.java b/compiler/src/test/java/mxml/tags/MXMLFeatureTestsBase.java
index 3c7e343..c46ba75 100644
--- a/compiler/src/test/java/mxml/tags/MXMLFeatureTestsBase.java
+++ b/compiler/src/test/java/mxml/tags/MXMLFeatureTestsBase.java
@@ -52,6 +52,7 @@
  * 
  * @author Gordon Smith
  */
+@SuppressWarnings("deprecation")
 public class MXMLFeatureTestsBase
 {
 	private static boolean generateResultFile = false;
diff --git a/compiler/src/test/java/org/apache/royale/compiler/internal/css/CSSStringPropertyValueTests.java b/compiler/src/test/java/org/apache/royale/compiler/internal/css/CSSStringPropertyValueTests.java
index df1b1b8..930f03b 100644
--- a/compiler/src/test/java/org/apache/royale/compiler/internal/css/CSSStringPropertyValueTests.java
+++ b/compiler/src/test/java/org/apache/royale/compiler/internal/css/CSSStringPropertyValueTests.java
@@ -26,7 +26,6 @@
 import java.util.List;
 
 import org.apache.royale.compiler.css.ICSSPropertyValue;
-import org.junit.Ignore;
 import org.junit.Test;
 
 /**
diff --git a/compiler/src/test/resources/swfdumps/as_ASNamespaceTests_ASNamespace_package_swfdump.xml b/compiler/src/test/resources/swfdumps/as_ASNamespaceTests_ASNamespace_package_swfdump.xml
index 84fe835..159752e 100644
--- a/compiler/src/test/resources/swfdumps/as_ASNamespaceTests_ASNamespace_package_swfdump.xml
+++ b/compiler/src/test/resources/swfdumps/as_ASNamespaceTests_ASNamespace_package_swfdump.xml
@@ -72,20 +72,20 @@
       succs=[]
       0       getlocal0                                
       1       pushscope                                
-      2       findpropstrict  chrome::app              
+      2       findpropstrict  Intl::Collator              
       3       constructprop                            
-      4       coerce          chrome::app              
+      4       coerce          Intl::Collator              
       5       setlocal2                                
-      6       findpropstrict  chrome::app              
+      6       findpropstrict  Intl::Collator              
       7       constructprop                            
-      8       coerce          chrome::app              
+      8       coerce          Intl::Collator              
       9       setlocal3                                
       10      getlocal3                                
-      11      getlex          chrome::app              
+      11      getlex          Intl::Collator              
       12      istypelate                               
       13      setlocal                              4  
       14      getlocal2                                
-      15      getlex          chrome::app              
+      15      getlex          Intl::Collator              
       16      istypelate                               
       17      setlocal                              5  
       18      findpropstrict  assertEqual              
diff --git a/compiler/src/test/resources/swfdumps/as_ASVariableTests_ASVariableTests_AnyInitializeUndefined_swfdump.xml b/compiler/src/test/resources/swfdumps/as_ASVariableTests_ASVariableTests_AnyInitializeUndefined_swfdump.xml
index ec1d085..1bdb14a 100644
--- a/compiler/src/test/resources/swfdumps/as_ASVariableTests_ASVariableTests_AnyInitializeUndefined_swfdump.xml
+++ b/compiler/src/test/resources/swfdumps/as_ASVariableTests_ASVariableTests_AnyInitializeUndefined_swfdump.xml
@@ -67,15 +67,15 @@
     //  max_regs     2            
     //  scope_depth  0            
     //  max_scope    1            
-    //  code_length  14           
+    //  code_length  12           
     bb0
       succs=[]
       0      getlocal0                       
       1      pushscope                       
       2      findpropstrict  assertEqual     
       3      pushstring      "null"          
-      4      pushbyte                     0  
-      5      pushbyte                     0  
+      4      pushundefined                   
+      5      pushundefined                   
       6      callpropvoid                    
       7      returnvoid                      
   }
@@ -108,7 +108,7 @@
       0      returnvoid      
   }
 
-  public static const foo:* = 0
+  public static const foo:*
 }
 
 function script0$init():*
diff --git a/compiler/src/test/resources/swfdumps/as_ASVariableTests_ASVariableTests_stringInitializeUndefined_swfdump.xml b/compiler/src/test/resources/swfdumps/as_ASVariableTests_ASVariableTests_stringInitializeUndefined_swfdump.xml
index 88f1f0d..f39f57a 100644
--- a/compiler/src/test/resources/swfdumps/as_ASVariableTests_ASVariableTests_stringInitializeUndefined_swfdump.xml
+++ b/compiler/src/test/resources/swfdumps/as_ASVariableTests_ASVariableTests_stringInitializeUndefined_swfdump.xml
@@ -74,7 +74,7 @@
       1      pushscope                       
       2      findpropstrict  assertEqual     
       3      pushstring      "null"          
-      4      pushbyte                     0  
+      4      getlex          foo
       5      pushnull                        
       6      callpropvoid                    
       7      returnvoid                      
@@ -108,7 +108,7 @@
       0      returnvoid      
   }
 
-  public static const foo:String = "0"
+  public static const foo:String
 }
 
 function script0$init():*
diff --git a/compiler-externc/src/test/royale/XML.as b/compiler/src/test/royale/XML.as
similarity index 100%
rename from compiler-externc/src/test/royale/XML.as
rename to compiler/src/test/royale/XML.as
diff --git a/compiler-externc/src/test/royale/XMLList.as b/compiler/src/test/royale/XMLList.as
similarity index 100%
rename from compiler-externc/src/test/royale/XMLList.as
rename to compiler/src/test/royale/XMLList.as
diff --git a/debugger/pom.xml b/debugger/pom.xml
index 798627e..9bad8f8 100644
--- a/debugger/pom.xml
+++ b/debugger/pom.xml
@@ -1,133 +1,139 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.apache.royale.compiler</groupId>
-    <artifactId>royale-compiler-parent</artifactId>
-    <version>0.9.4</version>
-  </parent>
-
-  <artifactId>debugger</artifactId>
-  <version>0.9.4</version>
-
-  <name>Apache Royale: Compiler: Debugger</name>
-
-  <build>
-    <plugins>
-      <!--
-Do all the JBurg code generation.
--->
-      <plugin>
-        <groupId>net.sourceforge.jburg</groupId>
-        <artifactId>jburg-maven-plugin</artifactId>
-        <version>1.10.4</version>
-        <extensions>true</extensions>
-        <executions>
-          <execution>
-            <id>generate-debugger</id>
-            <goals>
-              <goal>generate</goal>
-            </goals>
-            <configuration>
-              <includes>
-                <include>AS3DebuggerBURM.jbg</include>
-                <!--include>AS3DebuggerCompoundAssignmentRules.jbg</include>
-                <include>AS3DebuggerRules.jbg</include-->
-              </includes>
-              <sourceDirectory>src/main/jburg/flash/tools/debugger/expression</sourceDirectory>
-              <outputDirectory>target/generated-sources/jburg/flash/tools/debugger/expression</outputDirectory>
-            </configuration>
-          </execution>
-        </executions>
-        <configuration>
-          <!-- debug=true generates the "dump" method for Emitters, which is used for debugging -->
-          <!--debug>true</debug-->
-        </configuration>
-        <dependencies>
-          <dependency>
-            <groupId>net.sourceforge.jburg</groupId>
-            <artifactId>jburg</artifactId>
-            <version>1.10.3</version>
-          </dependency>
-          <dependency>
-            <groupId>org.apache.royale.compiler</groupId>
-            <artifactId>compiler-jburg-types</artifactId>
-            <version>${compiler-build-tools.version}</version>
-          </dependency>
-        </dependencies>
-      </plugin>
-    </plugins>
-  </build>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>compiler</artifactId>
-      <version>0.9.4</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>swfutils</artifactId>
-      <version>0.9.4</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-lang</groupId>
-      <artifactId>commons-lang</artifactId>
-      <version>2.6</version>
-    </dependency>
-
-    <dependency>
-      <groupId>args4j</groupId>
-      <artifactId>args4j</artifactId>
-      <version>2.0.28</version>
-    </dependency>
-    <dependency>
-      <groupId>org.codeartisans</groupId>
-      <artifactId>org.json</artifactId>
-      <version>20131017</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.javascript</groupId>
-      <artifactId>closure-compiler</artifactId>
-      <version>v20151015</version>
-    </dependency>
-    <dependency>
-      <groupId>org.clojure</groupId>
-      <artifactId>google-closure-library</artifactId>
-      <version>0.0-20150902-b129bb9e</version>
-    </dependency>
-
-   <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>compiler-build-tools</artifactId>
-      <version>${compiler-build-tools.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>4.10</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+

+  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.

+

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+  <modelVersion>4.0.0</modelVersion>

+

+  <parent>

+    <groupId>org.apache.royale.compiler</groupId>

+    <artifactId>royale-compiler-parent</artifactId>

+    <version>0.9.6</version>

+  </parent>

+

+  <artifactId>debugger</artifactId>

+  <version>0.9.6</version>

+

+  <name>Apache Royale: Compiler: Debugger</name>

+

+  <build>

+    <plugins>

+      <plugin>

+        <groupId>io.github.zlika</groupId>

+        <artifactId>reproducible-build-maven-plugin</artifactId>

+        <version>0.9</version>

+      </plugin>

+      <!--

+Do all the JBurg code generation.

+-->

+      <plugin>

+        <groupId>net.sourceforge.jburg</groupId>

+        <artifactId>jburg-maven-plugin</artifactId>

+        <version>1.10.4</version>

+        <extensions>true</extensions>

+        <executions>

+          <execution>

+            <id>generate-debugger</id>

+            <goals>

+              <goal>generate</goal>

+            </goals>

+            <configuration>

+              <includes>

+                <include>AS3DebuggerBURM.jbg</include>

+                <!--include>AS3DebuggerCompoundAssignmentRules.jbg</include>

+                <include>AS3DebuggerRules.jbg</include-->

+              </includes>

+              <sourceDirectory>src/main/jburg/flash/tools/debugger/expression</sourceDirectory>

+              <outputDirectory>target/generated-sources/jburg/flash/tools/debugger/expression</outputDirectory>

+            </configuration>

+          </execution>

+        </executions>

+        <configuration>

+          <!-- debug=true generates the "dump" method for Emitters, which is used for debugging -->

+          <!--debug>true</debug-->

+        </configuration>

+        <dependencies>

+            <!-- this needs to be first in order to patch jburg -->

+          <dependency>

+            <groupId>org.apache.royale.compiler</groupId>

+            <artifactId>compiler-jburg-types</artifactId>

+            <version>${compiler-build-tools.version}</version>

+          </dependency>

+          <dependency>

+            <groupId>net.sourceforge.jburg</groupId>

+            <artifactId>jburg</artifactId>

+            <version>1.10.3</version>

+          </dependency>

+        </dependencies>

+      </plugin>

+    </plugins>

+  </build>

+

+  <dependencies>

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>compiler</artifactId>

+      <version>0.9.6</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>swfutils</artifactId>

+      <version>0.9.6</version>

+    </dependency>

+    <dependency>

+      <groupId>commons-lang</groupId>

+      <artifactId>commons-lang</artifactId>

+      <version>2.6</version>

+    </dependency>

+

+    <dependency>

+      <groupId>args4j</groupId>

+      <artifactId>args4j</artifactId>

+      <version>2.0.28</version>

+    </dependency>

+    <dependency>

+      <groupId>org.codeartisans</groupId>

+      <artifactId>org.json</artifactId>

+      <version>20131017</version>

+    </dependency>

+    <dependency>

+      <groupId>com.google.javascript</groupId>

+      <artifactId>closure-compiler</artifactId>

+      <version>v20151015</version>

+    </dependency>

+    <dependency>

+      <groupId>org.clojure</groupId>

+      <artifactId>google-closure-library</artifactId>

+      <version>0.0-20150902-b129bb9e</version>

+    </dependency>

+

+   <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>compiler-build-tools</artifactId>

+      <version>${compiler-build-tools.version}</version>

+      <scope>test</scope>

+    </dependency>

+    <dependency>

+      <groupId>junit</groupId>

+      <artifactId>junit</artifactId>

+      <version>4.10</version>

+      <scope>test</scope>

+    </dependency>

+  </dependencies>

+

+</project>

diff --git a/debugger/src/main/java/flash/tools/debugger/expression/DebuggerUtil.java b/debugger/src/main/java/flash/tools/debugger/expression/DebuggerUtil.java
index c9dd112..6c07e10 100644
--- a/debugger/src/main/java/flash/tools/debugger/expression/DebuggerUtil.java
+++ b/debugger/src/main/java/flash/tools/debugger/expression/DebuggerUtil.java
@@ -95,6 +95,11 @@
     		return 0;
     	}
     	
+        @Override
+        public void setLastModified(long fileDate) {
+            // TODO Auto-generated method stub
+        }
+
     	public boolean isOpenDocument()
     	{
     		return false;
diff --git a/flex-compiler-oem/pom.xml b/flex-compiler-oem/pom.xml
index dd20460..ad80a59 100644
--- a/flex-compiler-oem/pom.xml
+++ b/flex-compiler-oem/pom.xml
@@ -1,52 +1,62 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.apache.royale.compiler</groupId>
-    <artifactId>royale-compiler-parent</artifactId>
-    <version>0.9.4</version>
-  </parent>
-
-  <artifactId>flex-compiler-oem</artifactId>
-  <version>0.9.4</version>
-
-  <name>Apache Royale: Compiler: OEM Layer</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>compiler</artifactId>
-      <version>0.9.4</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>compiler-jx</artifactId>
-      <version>0.9.4</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.royale.compiler</groupId>
-      <artifactId>swfutils</artifactId>
-      <version>0.9.4</version>
-    </dependency>
-  </dependencies>
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+

+  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.

+

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+  <modelVersion>4.0.0</modelVersion>

+

+  <parent>

+    <groupId>org.apache.royale.compiler</groupId>

+    <artifactId>royale-compiler-parent</artifactId>

+    <version>0.9.6</version>

+  </parent>

+

+  <artifactId>flex-compiler-oem</artifactId>

+  <version>0.9.6</version>

+

+  <name>Apache Royale: Compiler: OEM Layer</name>

+

+  <build>

+    <plugins>

+        <plugin>

+            <groupId>io.github.zlika</groupId>

+            <artifactId>reproducible-build-maven-plugin</artifactId>

+            <version>0.9</version>

+        </plugin>

+    </plugins>

+  </build>

+  

+  <dependencies>

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>compiler</artifactId>

+      <version>0.9.6</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>compiler-jx</artifactId>

+      <version>0.9.6</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.royale.compiler</groupId>

+      <artifactId>swfutils</artifactId>

+      <version>0.9.6</version>

+    </dependency>

+  </dependencies>

+

+</project>

diff --git a/jenkins.xml b/jenkins.xml
index 20adafb..ee47846 100644
--- a/jenkins.xml
+++ b/jenkins.xml
@@ -46,7 +46,7 @@
     
     <target name="jflex-download" description="Copies JFlex from JFlex website">
         <echo message="Be patient. This takes a few minutes..." />
-        <get src="http://jflex.de/${jflex.filename}.zip" dest="${jflex.temp.filename}" verbose="false" />
+        <get src="https://jflex.de/${jflex.filename}.zip" dest="${jflex.temp.filename}" verbose="false" />
         <unzip dest="${jflex.root}" src="${jflex.temp.filename}" />
     </target>
 
diff --git a/pom.xml b/pom.xml
index cfe9ec7..7e1dbce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,634 +1,749 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.apache</groupId>
-    <artifactId>apache</artifactId>
-    <version>18</version>
-  </parent>
-
-  <groupId>org.apache.royale.compiler</groupId>
-  <artifactId>royale-compiler-parent</artifactId>
-  <version>0.9.4</version>
-  <packaging>pom</packaging>
-
-  <name>Apache Royale: Compiler: Parent</name>
-  <description>The Apache Royale Project</description>
-
-  <scm>
-    <connection>scm:git:git@github.com:apache/royale-compiler.git</connection>
-    <developerConnection>scm:git:git@github.com:apache/royale-compiler.git</developerConnection>
-    <url>scm:git:git@github.com:apache/royale-compiler.git</url>
-    <tag>org.apache.royale.compiler-0.9.4-rc2</tag>
-  </scm>
-
-  <properties>
-    <java.version>1.6</java.version>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <project.reporting.outputencoding>UTF-8</project.reporting.outputencoding>
-    <maven.version>3.3.1</maven.version>
-
-    <flex.version>4.15.0</flex.version>
-    <flash.version>20.0</flash.version>
-    <air.version>20.0</air.version>
-
-    <jburgTypesRequired>true</jburgTypesRequired>
-    <compiler-build-tools.version>1.0.0</compiler-build-tools.version>
-    <compiler-jburg-types.version>1.0.0</compiler-jburg-types.version>
-
-    <!-- URL of the ASF SonarQube server -->
-    <sonar.host.url>https://builds.apache.org/analysis</sonar.host.url>
-    <!-- Tell sonar where the coverage reports are located -->
-    <sonar.jacoco.reportPath>${project.build.directory}/coverage-reports/jacoco-ut.exec</sonar.jacoco.reportPath>
-    <sonar.jacoco.itReportPath>${project.build.directory}/coverage-reports/jacoco-it.exec</sonar.jacoco.itReportPath>
-    <!-- Exclude all generated code -->
-    <sonar.exclusions>file:**/generated-sources/**</sonar.exclusions>
-
-    <website.path>latest-dev</website.path>
-  </properties>
-
-  <!-- Only configure the site distribution as the rest is handled by the apache parent -->
-  <distributionManagement>
-    <site>
-      <id>apache.website</id>
-      <url>scm:git:https://github.com/apache/royale-compiler.git</url>
-    </site>
-  </distributionManagement>
-
-  <issueManagement>
-    <system>GitHub</system>
-    <url>https://github.com/apache/royale-compiler/issues</url>
-  </issueManagement>
-
-  <mailingLists>
-    <mailingList>
-      <name>Apache Royale User List</name>
-      <subscribe>users-subscribe@royale.apache.org</subscribe>
-      <unsubscribe>users-unsubscribe@royale.apache.org</unsubscribe>
-      <post>users@royale.apache.org</post>
-      <archive>http://mail-archives.apache.org/mod_mbox/royale-users/</archive>
-    </mailingList>
-    <mailingList>
-      <name>Apache Royale Developer List</name>
-      <subscribe>dev-subscribe@royale.apache.org</subscribe>
-      <unsubscribe>dev-unsubscribe@royale.apache.org</unsubscribe>
-      <post>dev@royale.apache.org</post>
-      <archive>http://mail-archives.apache.org/mod_mbox/royale-dev/</archive>
-    </mailingList>
-  </mailingLists>
-
-  <!--
-      As the compiler build uses the jburg plugin which has a dependency on
-      the compiler-jburg-types artifact that are part of this project. We therefore have
-      a utils profile, that builds these these artifacts so Maven doesn't fail
-      as it resolves plugin dependencies before starting the build.
-      After one build with "-P -main,utils" (don't use main profile, use utils profile
-      has been built, the default build should be able to do it's job.
-  -->
-  <profiles>
-    <profile>
-      <id>utils</id>
-      <activation>
-          <activeByDefault>false</activeByDefault>
-      </activation>
-      <properties>
-          <jburgTypesRequired>false</jburgTypesRequired>
-      </properties>
-      <modules>
-        <module>compiler-build-tools</module>
-        <module>compiler-jburg-types</module>
-      </modules>
-    </profile>
-    <profile>
-        <id>main</id>
-        <activation>
-            <activeByDefault>true</activeByDefault>
-        </activation>
-        <modules>
-            <module>compiler-common</module>
-            <module>compiler-externc</module>
-            <module>compiler</module>
-            <module>compiler-jx</module>
-            <module>compiler-test-utils</module>
-            <module>swfutils</module>
-            <module>debugger</module>
-            <module>flex-compiler-oem</module>
-            <module>royale-ant-tasks</module>
-            <!--<module>royale-maven-extension</module>-->
-            <module>royale-maven-plugin</module>
-        </modules>
-        <build>
-          <plugins>
-            <plugin>
-              <groupId>net.sourceforge.jburg</groupId>
-              <artifactId>jburg-maven-plugin</artifactId>
-              <version>1.10.4</version>
-              <dependencies>
-                <dependency>
-                  <groupId>org.apache.royale.compiler</groupId>
-                  <artifactId>compiler-jburg-types</artifactId>
-                  <version>${compiler-jburg-types.version}</version>
-                </dependency>
-              </dependencies>
-            </plugin>
-          </plugins>
-        </build>
-    </profile>
-    <profile>
-      <id>apache-release</id>
-      <activation>
-          <activeByDefault>false</activeByDefault>
-      </activation>
-      <properties>
-        <website.path>${project.version}</website.path>
-      </properties>
-    </profile>
-  </profiles>
-
-  <build>
-    <plugins>
-      <!-- Check if all source files have the required apache license headers -->
-      <plugin>
-        <groupId>org.apache.rat</groupId>
-        <artifactId>apache-rat-plugin</artifactId>
-        <version>0.12</version>
-        <executions>
-          <execution>
-            <id>license-check</id>
-            <phase>verify</phase>
-            <goals>
-              <goal>check</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <excludes>
-            <exclude>LICENSE*</exclude>
-            <exclude>NOTICE*</exclude>
-            <exclude>README*</exclude>
-            <exclude>RELEASE_NOTES*</exclude>
-            <!-- Modules which are excluded from the build -->
-            <!-- FlashBuilder settings. frameworks/fb.properties contains Alex' path entries and should be removed -->
-            <exclude>fb.properties</exclude>
-            <!-- FlashBuilder / Eclipse settings. If checked in, they should have apache headers -->
-            <exclude>**/.settings/**</exclude>
-            <exclude>**/*.classpath</exclude>
-            <exclude>**/*.project</exclude>
-            <!-- Ignore IntelliJ IDEA project files -->
-            <exclude>**/*.iml</exclude>
-            <exclude>**/.idea/**</exclude>
-            <!-- Ignore VSCode/Java project files -->
-            <exclude>**/.factorypath</exclude>
-            <!--
-                Exclude any eventually existing content of target directories.
-                Some times when building with a bigger maven reactor and then
-                with a smaller one, RAT will complain about stuff still in the
-                target directories. We don't want that.
-            -->
-            <exclude>**/target/**</exclude>
-            <!-- Stuff an Ant build might have left behind. -->
-            <exclude>lib/**</exclude>
-            <!--
-                In case of an ANT based release the typedefs are included as a
-                subdirectory. We need to exclude this directory from the compiler checks
-                as the typedefs build will handle all content in that directory
-            -->
-            <exclude>royale-typedefs/**</exclude>
-          </excludes>
-        </configuration>
-        <dependencies>
-          <dependency>
-            <groupId>org.apache.maven.doxia</groupId>
-            <artifactId>doxia-core</artifactId>
-            <version>1.6</version>
-            <exclusions>
-              <exclusion>
-                <groupId>xerces</groupId>
-                <artifactId>xercesImpl</artifactId>
-              </exclusion>
-            </exclusions>
-          </dependency>
-        </dependencies>
-      </plugin>
-
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-dependency-plugin</artifactId>
-        <version>3.0.0</version>
-        <executions>
-          <execution>
-            <id>analyze</id>
-            <goals>
-              <goal>analyze-only</goal>
-            </goals>
-            <configuration>
-              <failOnWarning>false</failOnWarning>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <version>3.5.1</version>
-        <configuration>
-          <source>${java.version}</source>
-          <target>${java.version}</target>
-        </configuration>
-      </plugin>
-
-      <plugin>
-        <groupId>org.jacoco</groupId>
-        <artifactId>jacoco-maven-plugin</artifactId>
-        <version>0.7.9</version>
-        <executions>
-          <!--
-              Prepares the property pointing to the JaCoCo runtime agent which
-              is passed as VM argument when Maven the Surefire plugin is executed.
-          -->
-          <execution>
-            <id>pre-unit-test</id>
-            <goals>
-              <goal>prepare-agent</goal>
-            </goals>
-            <configuration>
-              <!-- Sets the path to the file which contains the execution data. -->
-              <destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
-              <!--
-                  Sets the name of the property containing the settings
-                  for JaCoCo runtime agent.
-              -->
-              <propertyName>surefireArgLine</propertyName>
-            </configuration>
-          </execution>
-          <!--
-              Ensures that the code coverage report for unit tests is created after
-              unit tests have been run.
-          -->
-          <execution>
-            <id>post-unit-test</id>
-            <phase>test</phase>
-            <goals>
-              <goal>report</goal>
-            </goals>
-            <configuration>
-              <!-- Sets the path to the file which contains the execution data. -->
-              <dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
-              <!-- Sets the output directory for the code coverage report. -->
-              <outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
-            </configuration>
-          </execution>
-          <!--
-              Prepares the property pointing to the JaCoCo runtime agent which
-              is passed as VM argument when Maven the Failsafe plugin is executed.
-          -->
-          <execution>
-            <id>pre-integration-test</id>
-            <phase>pre-integration-test</phase>
-            <goals>
-              <goal>prepare-agent</goal>
-            </goals>
-            <configuration>
-              <!-- Sets the path to the file which contains the execution data. -->
-              <destFile>${project.build.directory}/coverage-reports/jacoco-it.exec</destFile>
-              <!--
-                  Sets the name of the property containing the settings
-                  for JaCoCo runtime agent.
-              -->
-              <propertyName>failsafeArgLine</propertyName>
-            </configuration>
-          </execution>
-          <!--
-              Ensures that the code coverage report for integration tests after
-              integration tests have been run.
-          -->
-          <execution>
-            <id>post-integration-test</id>
-            <phase>post-integration-test</phase>
-            <goals>
-              <goal>report</goal>
-            </goals>
-            <configuration>
-              <!-- Sets the path to the file which contains the execution data. -->
-              <dataFile>${project.build.directory}/coverage-reports/jacoco-it.exec</dataFile>
-              <!-- Sets the output directory for the code coverage report. -->
-              <outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-
-      <!-- Make the surefire execute all unit-tests -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <version>2.19</version>
-        <configuration>
-          <argLine>${surefireArgLine}</argLine>
-          <systemPropertyVariables>
-            <buildType>Maven</buildType>
-            <flexVersion>${flex.version}</flexVersion>
-            <flashVersion>${flash.version}</flashVersion>
-            <airVersion>${air.version}</airVersion>
-            <mavenLocalRepoDir>${settings.localRepository}</mavenLocalRepoDir>
-          </systemPropertyVariables>
-          <!--
-              Currently some tests need this to be disabled,
-              but actually this is a bug. For now I'll disable
-              them to avoid problems during the maven migration.
-              After this is finished, we should defnitely fix
-              the tests so assertions can be enabled.
-          -->
-          <enableAssertions>false</enableAssertions>
-        </configuration>
-      </plugin>
-
-      <!-- Make the failsafe execute all integration-tests -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-failsafe-plugin</artifactId>
-        <version>2.18.1</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>integration-test</goal>
-              <goal>verify</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <argLine>${failsafeArgLine}</argLine>
-          <systemPropertyVariables>
-            <buildType>Maven</buildType>
-            <flexVersion>${flex.version}</flexVersion>
-            <flashVersion>${flash.version}</flashVersion>
-            <airVersion>${air.version}</airVersion>
-            <mavenLocalRepoDir>${settings.localRepository}</mavenLocalRepoDir>
-            <FLASHPLAYER_DEBUGGER>${env.FLASHPLAYER_DEBUGGER}</FLASHPLAYER_DEBUGGER>
-          </systemPropertyVariables>
-        </configuration>
-      </plugin>
-
-      <!-- Plugin to detect problems with JDK incompatibilities -->
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>animal-sniffer-maven-plugin</artifactId>
-        <version>1.15</version>
-        <executions>
-          <execution>
-            <id>check-jdk-1.6</id>
-            <phase>test</phase>
-            <goals>
-              <goal>check</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <signature>
-            <groupId>org.codehaus.mojo.signature</groupId>
-            <artifactId>java16</artifactId>
-            <version>1.1</version>
-          </signature>
-        </configuration>
-      </plugin>
-
-      <!-- Configure the Site generation -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-site-plugin</artifactId>
-        <!-- Downgraded to 3.4 as 3.5 and 3.5.1 seem to have issues with the velocity tools -->
-        <version>3.7.1</version>
-        <configuration>
-          <generateReports>true</generateReports>
-          <generateSitemap>true</generateSitemap>
-          <relativizeDecorationLinks>false</relativizeDecorationLinks>
-          <locales>en</locales>
-          <inputEncoding>${project.build.sourceEncoding}</inputEncoding>
-          <outputEncoding>${project.reporting.outputencoding}</outputEncoding>
-        </configuration>
-        <dependencies>
-          <dependency>
-            <groupId>commons-lang</groupId>
-            <artifactId>commons-lang</artifactId>
-            <version>2.6</version>
-          </dependency>
-          <dependency>
-            <groupId>org.apache.maven.doxia</groupId>
-            <artifactId>doxia-core</artifactId>
-            <version>1.6</version>
-          </dependency>
-          <!-- All dependencies needed by the reflow skin -->
-          <dependency>
-            <groupId>lt.velykis.maven.skins</groupId>
-            <artifactId>reflow-velocity-tools</artifactId>
-            <version>1.1.1</version>
-          </dependency>
-          <dependency>
-            <groupId>org.apache.velocity</groupId>
-            <artifactId>velocity</artifactId>
-            <version>1.7</version>
-          </dependency>
-        </dependencies>
-      </plugin>
-
-      <!--
-        Make the maven-site-plugin stage the output in the "asf-site" branch
-      -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-scm-publish-plugin</artifactId>
-        <version>3.0.0</version>
-        <executions>
-          <execution>
-            <id>scm-publish</id>
-            <phase>site-deploy</phase>
-            <!-- deploy site with maven-scm-publish-plugin -->
-            <goals>
-              <goal>publish-scm</goal>
-            </goals>
-            <configuration>
-              <!-- mono-module doesn't require site:stage -->
-              <content>${project.build.directory}/site</content>
-              <!-- branch where to deploy -->
-              <scmBranch>asf-site</scmBranch>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-javadoc-plugin</artifactId>
-        <version>2.10.4</version>
-      </plugin>
-
-      <plugin>
-        <groupId>org.sonarsource.scanner.maven</groupId>
-        <artifactId>sonar-maven-plugin</artifactId>
-        <version>3.2</version>
-      </plugin>
-    </plugins>
-
-    <pluginManagement>
-      <plugins>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-javadoc-plugin</artifactId>
-          <version>2.10.4</version>
-          <configuration>
-            <tags>
-              <tag>
-                <name>goal</name>
-                <placement>a</placement>
-                <head>Goal:</head>
-              </tag>
-              <tag>
-                <name>phase</name>
-                <placement>a</placement>
-                <head>Phase:</head>
-              </tag>
-              <tag>
-                <name>threadSafe</name>
-                <placement>a</placement>
-                <head>Thread Safe:</head>
-              </tag>
-              <tag>
-                <name>requiresDependencyResolution</name>
-                <placement>a</placement>
-                <head>Requires Dependency Resolution:</head>
-              </tag>
-              <tag>
-                <name>requiresProject</name>
-                <placement>a</placement>
-                <head>Requires Project:</head>
-              </tag>
-            </tags>
-            <!-- TODO: This should only be a measure of last resort -->
-            <failOnError>false</failOnError>
-          </configuration>
-        </plugin>
-        <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-scm-plugin</artifactId>
-            <version>1.10.0</version>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-resources-plugin</artifactId>
-          <version>3.1.0</version>
-        </plugin>
-      </plugins>
-    </pluginManagement>
-  </build>
-
-  <reporting>
-    <plugins>
-
-      <!-- Generates a changelog report from GIT commits -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-changelog-plugin</artifactId>
-        <version>2.3</version>
-        <configuration>
-          <!-- Automatically link Jira issues -->
-          <issueLinkUrl>https://issues.apache.org/jira/browse/%ISSUE%</issueLinkUrl>
-        </configuration>
-      </plugin>
-
-      <!-- Generates a report with the details of the unit- and integrationtests -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-report-plugin</artifactId>
-        <version>2.19.1</version>
-      </plugin>
-
-      <!-- Generates a report with the test coverages -->
-      <plugin>
-        <groupId>org.jacoco</groupId>
-        <artifactId>jacoco-maven-plugin</artifactId>
-        <version>0.7.9</version>
-      </plugin>
-
-      <!-- Generates a report with the SonarQube analysis reports -->
-      <plugin>
-        <groupId>org.codehaus.sonar-plugins</groupId>
-        <artifactId>maven-report</artifactId>
-        <version>0.1</version>
-      </plugin>
-
-      <!-- Generate the JavaDoc API documentation -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-javadoc-plugin</artifactId>
-        <version>2.10.4</version>
-      </plugin>
-    </plugins>
-  </reporting>
-
-  <repositories>
-    <repository>
-      <id>apache-release</id>
-      <url>https://repository.apache.org/content/repositories/releases</url>
-      <releases>
-        <enabled>true</enabled>
-      </releases>
-      <snapshots>
-        <enabled>false</enabled>
-      </snapshots>
-    </repository>
-    <repository>
-      <id>apache-snapshots</id>
-      <url>https://repository.apache.org/content/repositories/snapshots</url>
-      <releases>
-        <enabled>false</enabled>
-      </releases>
-      <snapshots>
-        <enabled>true</enabled>
-      </snapshots>
-    </repository>
-  </repositories>
-
-  <pluginRepositories>
-    <pluginRepository>
-      <id>apache-plugins-release</id>
-      <url>https://repository.apache.org/content/repositories/releases</url>
-      <releases>
-        <enabled>true</enabled>
-      </releases>
-      <snapshots>
-        <enabled>false</enabled>
-      </snapshots>
-    </pluginRepository>
-    <pluginRepository>
-      <id>apache-plugins-snapshots</id>
-      <url>https://repository.apache.org/content/repositories/snapshots</url>
-      <releases>
-        <enabled>false</enabled>
-      </releases>
-      <snapshots>
-        <enabled>true</enabled>
-      </snapshots>
-    </pluginRepository>
-  </pluginRepositories>
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+

+  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.

+

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+  <modelVersion>4.0.0</modelVersion>

+

+  <parent>

+    <groupId>org.apache</groupId>

+    <artifactId>apache</artifactId>

+    <version>18</version>

+  </parent>

+

+  <groupId>org.apache.royale.compiler</groupId>

+  <artifactId>royale-compiler-parent</artifactId>

+  <version>0.9.6</version>

+  <packaging>pom</packaging>

+

+  <name>Apache Royale: Compiler: Parent</name>

+  <description>The Apache Royale Project</description>

+

+  <scm>

+    <connection>scm:git:https://github.com/apache/royale-compiler.git</connection>

+    <developerConnection>scm:git:https://github.com/apache/royale-compiler.git</developerConnection>

+    <url>scm:git:https://github.com/apache/royale-compiler.git</url>

+    <tag>org.apache.royale.compiler-0.9.6-rc3</tag>

+  </scm>

+

+  <properties>

+    <java.version>1.6</java.version>

+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

+    <project.reporting.outputencoding>UTF-8</project.reporting.outputencoding>

+    <maven.version>3.3.1</maven.version>

+

+    <flex.version>4.15.0</flex.version>

+    <flash.version>20.0</flash.version>

+    <air.version>20.0</air.version>

+

+    <jburgTypesRequired>true</jburgTypesRequired>

+    <skipgpg>false</skipgpg>

+    <compiler-build-tools.version>1.1.0</compiler-build-tools.version>

+    <compiler-jburg-types.version>1.1.0</compiler-jburg-types.version>

+

+    <!-- URL of the ASF SonarQube server -->

+    <sonar.host.url>https://builds.apache.org/analysis</sonar.host.url>

+    <!-- Tell sonar where the coverage reports are located -->

+    <sonar.jacoco.reportPath>${project.build.directory}/coverage-reports/jacoco-ut.exec</sonar.jacoco.reportPath>

+    <sonar.jacoco.itReportPath>${project.build.directory}/coverage-reports/jacoco-it.exec</sonar.jacoco.itReportPath>

+    <!-- Exclude all generated code -->

+    <sonar.exclusions>file:**/generated-sources/**</sonar.exclusions>

+

+    <website.path>latest-dev</website.path>

+  </properties>

+

+  <!-- Only configure the site distribution as the rest is handled by the apache parent -->

+  <distributionManagement>

+    <site>

+      <id>apache.website</id>

+      <url>scm:git:https://github.com/apache/royale-compiler.git</url>

+    </site>

+  </distributionManagement>

+

+  <issueManagement>

+    <system>GitHub</system>

+    <url>https://github.com/apache/royale-compiler/issues</url>

+  </issueManagement>

+

+  <mailingLists>

+    <mailingList>

+      <name>Apache Royale User List</name>

+      <subscribe>users-subscribe@royale.apache.org</subscribe>

+      <unsubscribe>users-unsubscribe@royale.apache.org</unsubscribe>

+      <post>users@royale.apache.org</post>

+      <archive>http://mail-archives.apache.org/mod_mbox/royale-users/</archive>

+    </mailingList>

+    <mailingList>

+      <name>Apache Royale Developer List</name>

+      <subscribe>dev-subscribe@royale.apache.org</subscribe>

+      <unsubscribe>dev-unsubscribe@royale.apache.org</unsubscribe>

+      <post>dev@royale.apache.org</post>

+      <archive>http://mail-archives.apache.org/mod_mbox/royale-dev/</archive>

+    </mailingList>

+  </mailingLists>

+

+  <!--

+      As the compiler build uses the jburg plugin which has a dependency on

+      the compiler-jburg-types artifact that are part of this project. We therefore have

+      a utils profile, that builds these these artifacts so Maven doesn't fail

+      as it resolves plugin dependencies before starting the build.

+      After one build with "-P -main,utils" (don't use main profile, use utils profile

+      has been built, the default build should be able to do it's job.

+  -->

+  <profiles>

+    <profile>

+      <id>utils</id>

+      <activation>

+          <activeByDefault>false</activeByDefault>

+      </activation>

+      <properties>

+          <jburgTypesRequired>false</jburgTypesRequired>

+      </properties>

+      <modules>

+        <module>compiler-build-tools</module>

+        <module>compiler-jburg-types</module>

+      </modules>

+      <build>

+        <plugins>

+          <plugin>

+            <groupId>org.apache.maven.plugins</groupId>

+            <artifactId>maven-gpg-plugin</artifactId>

+            <configuration>

+              <skip>${skipgpg}</skip><!--true to skip gpg if building release on CI server -->

+            </configuration>

+          </plugin>

+          <plugin>

+            <groupId>org.apache.maven.plugins</groupId>

+            <artifactId>maven-release-plugin</artifactId>

+            <version>2.5.3</version>

+            <configuration>

+              <providerImplementations>

+                <git>jgit</git>

+              </providerImplementations>

+            </configuration>

+            <dependencies>

+              <dependency>

+                <groupId>org.apache.maven.scm</groupId>

+                <artifactId>maven-scm-provider-jgit</artifactId>

+                <version>1.11.2-SNAPSHOT</version>

+              </dependency>

+              <dependency>

+                <groupId>org.apache.maven.scm</groupId>

+                <artifactId>maven-scm-api</artifactId>

+                <version>1.11.2-SNAPSHOT</version>

+              </dependency>

+            </dependencies>

+          </plugin>

+        </plugins>

+      </build>

+    </profile>

+    <profile>

+        <id>main</id>

+        <activation>

+            <activeByDefault>true</activeByDefault>

+        </activation>

+        <modules>

+            <module>compiler-common</module>

+            <module>compiler-externc</module>

+            <module>compiler</module>

+            <module>compiler-jx</module>

+            <module>compiler-test-utils</module>

+            <module>swfutils</module>

+            <module>debugger</module>

+            <module>flex-compiler-oem</module>

+            <module>royale-ant-tasks</module>

+            <module>royaleunit-ant-tasks</module>

+            <!--<module>royale-maven-extension</module>-->

+            <module>royale-maven-plugin</module>

+        </modules>

+        <build>

+          <plugins>

+            <plugin>

+              <groupId>net.sourceforge.jburg</groupId>

+              <artifactId>jburg-maven-plugin</artifactId>

+              <version>1.10.4</version>

+              <dependencies>

+                <dependency>

+                  <groupId>org.apache.royale.compiler</groupId>

+                  <artifactId>compiler-jburg-types</artifactId>

+                  <version>${compiler-jburg-types.version}</version>

+                </dependency>

+              </dependencies>

+            </plugin>

+            <plugin>

+                <groupId>org.apache.maven.plugins</groupId>

+                <artifactId>maven-release-plugin</artifactId>

+                <version>2.5.3</version>

+                <configuration>

+                    <providerImplementations>

+                        <git>jgit</git>

+                    </providerImplementations>

+                </configuration>

+                <dependencies>

+                    <dependency>

+                        <groupId>org.apache.maven.scm</groupId>

+                        <artifactId>maven-scm-provider-jgit</artifactId>

+                        <version>1.11.2-SNAPSHOT</version>

+                    </dependency>

+                    <dependency>

+                        <groupId>org.apache.maven.scm</groupId>

+                        <artifactId>maven-scm-api</artifactId>

+                        <version>1.11.2-SNAPSHOT</version>

+                    </dependency>

+                </dependencies>

+            </plugin>

+          </plugins>

+        </build>

+    </profile>

+    <profile>

+      <id>apache-release</id>

+      <activation>

+          <activeByDefault>false</activeByDefault>

+      </activation>

+      <properties>

+        <website.path>${project.version}</website.path>

+      </properties>

+    </profile>

+    <profile>

+        <id>upload-release-to-staging</id>

+        <activation>

+            <activeByDefault>false</activeByDefault>

+        </activation>

+        <modules><!-- only run on top-level, not for each module -->

+        </modules>

+        <build>

+            <plugins>

+                <plugin>

+                    <groupId>org.codehaus.mojo</groupId>

+                    <artifactId>wagon-maven-plugin</artifactId>

+                    <version>2.0.0</version>

+                    <configuration>

+                        <includes>**</includes>

+                        <serverId>apache.releases.https</serverId>

+                        <url>https://repository.apache.org/service/local/staging/deploy/maven2</url>

+                    </configuration>

+                </plugin>

+            </plugins>

+        </build>

+    </profile>

+    <profile>

+        <id>test-using-swf</id>

+        <dependencies>

+            <dependency>

+                <groupId>com.adobe.flash.framework</groupId>

+                <artifactId>playerglobal</artifactId>

+                <version>${flash.version}</version>

+                <type>swc</type>

+                <scope>test</scope>

+            </dependency>

+        </dependencies>

+    </profile>

+  </profiles>

+

+  <build>

+    <plugins>

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-gpg-plugin</artifactId>

+        <configuration>

+          <skip>${skipgpg}</skip><!--true to skip gpg if building release on CI server -->

+        </configuration>

+      </plugin>

+      <!-- Check if all source files have the required apache license headers -->

+      <plugin>

+        <groupId>org.apache.rat</groupId>

+        <artifactId>apache-rat-plugin</artifactId>

+        <version>0.12</version>

+        <executions>

+          <execution>

+            <id>license-check</id>

+            <phase>verify</phase>

+            <goals>

+              <goal>check</goal>

+            </goals>

+          </execution>

+        </executions>

+        <configuration>

+          <excludes>

+            <exclude>LICENSE*</exclude>

+            <exclude>NOTICE*</exclude>

+            <exclude>README*</exclude>

+            <exclude>RELEASE_NOTES*</exclude>

+            <!-- Modules which are excluded from the build -->

+            <!-- FlashBuilder settings. frameworks/fb.properties contains Alex' path entries and should be removed -->

+            <exclude>fb.properties</exclude>

+            <!-- FlashBuilder / Eclipse settings. If checked in, they should have apache headers -->

+            <exclude>**/.settings/**</exclude>

+            <exclude>**/*.classpath</exclude>

+            <exclude>**/*.project</exclude>

+            <!-- Ignore IntelliJ IDEA project files -->

+            <exclude>**/*.iml</exclude>

+            <exclude>**/.idea/**</exclude>

+            <!-- Ignore VSCode/Java project files -->

+            <exclude>**/.factorypath</exclude>

+            <!--

+                Exclude any eventually existing content of target directories.

+                Some times when building with a bigger maven reactor and then

+                with a smaller one, RAT will complain about stuff still in the

+                target directories. We don't want that.

+            -->

+            <exclude>**/target/**</exclude>

+            <exclude>**/release-dir/**</exclude>

+            <!-- Stuff an Ant build might have left behind. -->

+            <exclude>lib/**</exclude>

+            <!--

+                In case of an ANT based release the typedefs are included as a

+                subdirectory. We need to exclude this directory from the compiler checks

+                as the typedefs build will handle all content in that directory

+            -->

+            <exclude>royale-typedefs/**</exclude>

+            <!-- This file is used to get reproducible builds.  See royale-maven-plugin/pom.xml

+                 for more info.

+             -->

+            <exclude>**/src/main/sisu/javax.inject.Named</exclude>

+          </excludes>

+        </configuration>

+        <dependencies>

+          <dependency>

+            <groupId>org.apache.maven.doxia</groupId>

+            <artifactId>doxia-core</artifactId>

+            <version>1.6</version>

+            <exclusions>

+              <exclusion>

+                <groupId>xerces</groupId>

+                <artifactId>xercesImpl</artifactId>

+              </exclusion>

+            </exclusions>

+          </dependency>

+        </dependencies>

+      </plugin>

+

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-dependency-plugin</artifactId>

+        <version>3.0.0</version>

+        <executions>

+          <execution>

+            <id>analyze</id>

+            <goals>

+              <goal>analyze-only</goal>

+            </goals>

+            <configuration>

+              <failOnWarning>false</failOnWarning>

+            </configuration>

+          </execution>

+        </executions>

+      </plugin>

+

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-compiler-plugin</artifactId>

+        <version>3.5.1</version>

+        <configuration>

+          <source>${java.version}</source>

+          <target>${java.version}</target>

+        </configuration>

+      </plugin>

+

+      <plugin>

+        <groupId>org.jacoco</groupId>

+        <artifactId>jacoco-maven-plugin</artifactId>

+        <version>0.7.9</version>

+        <executions>

+          <!--

+              Prepares the property pointing to the JaCoCo runtime agent which

+              is passed as VM argument when Maven the Surefire plugin is executed.

+          -->

+          <execution>

+            <id>pre-unit-test</id>

+            <goals>

+              <goal>prepare-agent</goal>

+            </goals>

+            <configuration>

+              <!-- Sets the path to the file which contains the execution data. -->

+              <destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>

+              <!--

+                  Sets the name of the property containing the settings

+                  for JaCoCo runtime agent.

+              -->

+              <propertyName>surefireArgLine</propertyName>

+            </configuration>

+          </execution>

+          <!--

+              Ensures that the code coverage report for unit tests is created after

+              unit tests have been run.

+          -->

+          <execution>

+            <id>post-unit-test</id>

+            <phase>test</phase>

+            <goals>

+              <goal>report</goal>

+            </goals>

+            <configuration>

+              <!-- Sets the path to the file which contains the execution data. -->

+              <dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>

+              <!-- Sets the output directory for the code coverage report. -->

+              <outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>

+            </configuration>

+          </execution>

+          <!--

+              Prepares the property pointing to the JaCoCo runtime agent which

+              is passed as VM argument when Maven the Failsafe plugin is executed.

+          -->

+          <execution>

+            <id>pre-integration-test</id>

+            <phase>pre-integration-test</phase>

+            <goals>

+              <goal>prepare-agent</goal>

+            </goals>

+            <configuration>

+              <!-- Sets the path to the file which contains the execution data. -->

+              <destFile>${project.build.directory}/coverage-reports/jacoco-it.exec</destFile>

+              <!--

+                  Sets the name of the property containing the settings

+                  for JaCoCo runtime agent.

+              -->

+              <propertyName>failsafeArgLine</propertyName>

+            </configuration>

+          </execution>

+          <!--

+              Ensures that the code coverage report for integration tests after

+              integration tests have been run.

+          -->

+          <execution>

+            <id>post-integration-test</id>

+            <phase>post-integration-test</phase>

+            <goals>

+              <goal>report</goal>

+            </goals>

+            <configuration>

+              <!-- Sets the path to the file which contains the execution data. -->

+              <dataFile>${project.build.directory}/coverage-reports/jacoco-it.exec</dataFile>

+              <!-- Sets the output directory for the code coverage report. -->

+              <outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>

+            </configuration>

+          </execution>

+        </executions>

+      </plugin>

+

+      <!-- Make the surefire execute all unit-tests -->

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-surefire-plugin</artifactId>

+        <version>2.19</version>

+        <configuration>

+          <argLine>${surefireArgLine}</argLine>

+          <systemPropertyVariables>

+            <buildType>Maven</buildType>

+            <flexVersion>${flex.version}</flexVersion>

+            <flashVersion>${flash.version}</flashVersion>

+            <airVersion>${air.version}</airVersion>

+            <mavenLocalRepoDir>${settings.localRepository}</mavenLocalRepoDir>

+          </systemPropertyVariables>

+          <!--

+              Currently some tests need this to be disabled,

+              but actually this is a bug. For now I'll disable

+              them to avoid problems during the maven migration.

+              After this is finished, we should defnitely fix

+              the tests so assertions can be enabled.

+          -->

+          <enableAssertions>false</enableAssertions>

+        </configuration>

+      </plugin>

+

+      <!-- Make the failsafe execute all integration-tests -->

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-failsafe-plugin</artifactId>

+        <version>2.18.1</version>

+        <executions>

+          <execution>

+            <goals>

+              <goal>integration-test</goal>

+              <goal>verify</goal>

+            </goals>

+          </execution>

+        </executions>

+        <configuration>

+          <argLine>${failsafeArgLine}</argLine>

+          <systemPropertyVariables>

+            <buildType>Maven</buildType>

+            <flexVersion>${flex.version}</flexVersion>

+            <flashVersion>${flash.version}</flashVersion>

+            <airVersion>${air.version}</airVersion>

+            <mavenLocalRepoDir>${settings.localRepository}</mavenLocalRepoDir>

+            <FLASHPLAYER_DEBUGGER>${env.FLASHPLAYER_DEBUGGER}</FLASHPLAYER_DEBUGGER>

+          </systemPropertyVariables>

+        </configuration>

+      </plugin>

+

+      <!-- Plugin to detect problems with JDK incompatibilities -->

+      <plugin>

+        <groupId>org.codehaus.mojo</groupId>

+        <artifactId>animal-sniffer-maven-plugin</artifactId>

+        <version>1.15</version>

+        <executions>

+          <execution>

+            <id>check-jdk-1.6</id>

+            <phase>test</phase>

+            <goals>

+              <goal>check</goal>

+            </goals>

+          </execution>

+        </executions>

+        <configuration>

+          <signature>

+            <groupId>org.codehaus.mojo.signature</groupId>

+            <artifactId>java16</artifactId>

+            <version>1.1</version>

+          </signature>

+        </configuration>

+      </plugin>

+

+      <!-- Configure the Site generation -->

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-site-plugin</artifactId>

+        <!-- Downgraded to 3.4 as 3.5 and 3.5.1 seem to have issues with the velocity tools -->

+        <version>3.7.1</version>

+        <configuration>

+          <generateReports>true</generateReports>

+          <generateSitemap>true</generateSitemap>

+          <relativizeDecorationLinks>false</relativizeDecorationLinks>

+          <locales>en</locales>

+          <inputEncoding>${project.build.sourceEncoding}</inputEncoding>

+          <outputEncoding>${project.reporting.outputencoding}</outputEncoding>

+        </configuration>

+        <dependencies>

+          <dependency>

+            <groupId>commons-lang</groupId>

+            <artifactId>commons-lang</artifactId>

+            <version>2.6</version>

+          </dependency>

+          <dependency>

+            <groupId>org.apache.maven.doxia</groupId>

+            <artifactId>doxia-core</artifactId>

+            <version>1.6</version>

+          </dependency>

+          <!-- All dependencies needed by the reflow skin -->

+          <dependency>

+            <groupId>lt.velykis.maven.skins</groupId>

+            <artifactId>reflow-velocity-tools</artifactId>

+            <version>1.1.1</version>

+          </dependency>

+          <dependency>

+            <groupId>org.apache.velocity</groupId>

+            <artifactId>velocity</artifactId>

+            <version>1.7</version>

+          </dependency>

+        </dependencies>

+      </plugin>

+

+      <!--

+        Make the maven-site-plugin stage the output in the "asf-site" branch

+      -->

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-scm-publish-plugin</artifactId>

+        <version>3.0.0</version>

+        <executions>

+          <execution>

+            <id>scm-publish</id>

+            <phase>site-deploy</phase>

+            <!-- deploy site with maven-scm-publish-plugin -->

+            <goals>

+              <goal>publish-scm</goal>

+            </goals>

+            <configuration>

+              <!-- mono-module doesn't require site:stage -->

+              <content>${project.build.directory}/site</content>

+              <!-- branch where to deploy -->

+              <scmBranch>asf-site</scmBranch>

+            </configuration>

+          </execution>

+        </executions>

+      </plugin>

+

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-javadoc-plugin</artifactId>

+        <version>2.10.4</version>

+      </plugin>

+

+      <plugin>

+        <groupId>org.sonarsource.scanner.maven</groupId>

+        <artifactId>sonar-maven-plugin</artifactId>

+        <version>3.2</version>

+      </plugin>

+    </plugins>

+

+    <pluginManagement>

+      <plugins>

+        <plugin>

+          <groupId>io.github.zlika</groupId>

+          <artifactId>reproducible-build-maven-plugin</artifactId>

+          <version>0.9</version>

+          <executions>

+            <execution>

+              <goals>

+                <goal>strip-jar</goal>

+              </goals>

+            </execution>

+          </executions>

+        </plugin>

+        <plugin>

+          <groupId>org.apache.maven.plugins</groupId>

+          <artifactId>maven-javadoc-plugin</artifactId>

+          <version>2.10.4</version>

+          <configuration>

+            <tags>

+              <tag>

+                <name>goal</name>

+                <placement>a</placement>

+                <head>Goal:</head>

+              </tag>

+              <tag>

+                <name>phase</name>

+                <placement>a</placement>

+                <head>Phase:</head>

+              </tag>

+              <tag>

+                <name>threadSafe</name>

+                <placement>a</placement>

+                <head>Thread Safe:</head>

+              </tag>

+              <tag>

+                <name>requiresDependencyResolution</name>

+                <placement>a</placement>

+                <head>Requires Dependency Resolution:</head>

+              </tag>

+              <tag>

+                <name>requiresProject</name>

+                <placement>a</placement>

+                <head>Requires Project:</head>

+              </tag>

+            </tags>

+            <!-- TODO: This should only be a measure of last resort -->

+            <failOnError>false</failOnError>

+          </configuration>

+        </plugin>

+        <plugin>

+            <groupId>org.apache.maven.plugins</groupId>

+            <artifactId>maven-scm-plugin</artifactId>

+            <version>1.10.0</version>

+        </plugin>

+        <plugin>

+          <groupId>org.apache.maven.plugins</groupId>

+          <artifactId>maven-resources-plugin</artifactId>

+          <version>3.1.0</version>

+        </plugin>

+      </plugins>

+    </pluginManagement>

+  </build>

+

+  <reporting>

+    <plugins>

+

+      <!-- Generates a changelog report from GIT commits -->

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-changelog-plugin</artifactId>

+        <version>2.3</version>

+        <configuration>

+          <!-- Automatically link Jira issues -->

+          <issueLinkUrl>https://issues.apache.org/jira/browse/%ISSUE%</issueLinkUrl>

+        </configuration>

+      </plugin>

+

+      <!-- Generates a report with the details of the unit- and integrationtests -->

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-surefire-report-plugin</artifactId>

+        <version>2.19.1</version>

+      </plugin>

+

+      <!-- Generates a report with the test coverages -->

+      <plugin>

+        <groupId>org.jacoco</groupId>

+        <artifactId>jacoco-maven-plugin</artifactId>

+        <version>0.7.9</version>

+      </plugin>

+

+      <!-- Generates a report with the SonarQube analysis reports -->

+      <plugin>

+        <groupId>org.codehaus.sonar-plugins</groupId>

+        <artifactId>maven-report</artifactId>

+        <version>0.1</version>

+      </plugin>

+

+      <!-- Generate the JavaDoc API documentation -->

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-javadoc-plugin</artifactId>

+        <version>2.10.4</version>

+      </plugin>

+    </plugins>

+  </reporting>

+

+  <repositories>

+    <repository>

+      <id>apache-release</id>

+      <url>https://repository.apache.org/content/repositories/releases</url>

+      <releases>

+        <enabled>true</enabled>

+      </releases>

+      <snapshots>

+        <enabled>false</enabled>

+      </snapshots>

+    </repository>

+    <repository>

+      <id>apache-snapshots</id>

+      <url>https://repository.apache.org/content/repositories/snapshots</url>

+      <releases>

+        <enabled>false</enabled>

+      </releases>

+      <snapshots>

+        <enabled>true</enabled>

+      </snapshots>

+    </repository>

+  </repositories>

+

+  <pluginRepositories>

+    <pluginRepository>

+      <id>apache-plugins-release</id>

+      <url>https://repository.apache.org/content/repositories/releases</url>

+      <releases>

+        <enabled>true</enabled>

+      </releases>

+      <snapshots>

+        <enabled>false</enabled>

+      </snapshots>

+    </pluginRepository>

+    <pluginRepository>

+      <id>apache-plugins-snapshots</id>

+      <url>https://repository.apache.org/content/repositories/snapshots</url>

+      <releases>

+        <enabled>false</enabled>

+      </releases>

+      <snapshots>

+        <enabled>true</enabled>

+      </snapshots>

+    </pluginRepository>

+  </pluginRepositories>

+

+</project>

diff --git a/releasecandidate.xml b/releasecandidate.xml
index e4a50a8..d26e637 100644
--- a/releasecandidate.xml
+++ b/releasecandidate.xml
@@ -52,8 +52,8 @@
 	<property name="rat.report" value="${basedir}/rat-report.txt"/>
     <property name="apache.rat.jar" value="apache-rat-0.11.jar" />
     <property name="apache.rat.tasks.jar" value="apache-rat-tasks-0.11.jar" />
-    <property name="apache.rat.url" value="http://search.maven.org/remotecontent?filepath=org/apache/rat/apache-rat/0.11" />
-    <property name="apache.rat.tasks.url" value="http://search.maven.org/remotecontent?filepath=org/apache/rat/apache-rat-tasks/0.11" />
+    <property name="apache.rat.url" value="https://search.maven.org/remotecontent?filepath=org/apache/rat/apache-rat/0.11" />
+    <property name="apache.rat.tasks.url" value="https://search.maven.org/remotecontent?filepath=org/apache/rat/apache-rat-tasks/0.11" />
     
 	<property file="${basedir}/local.properties" />
 	<property file="${basedir}/build.properties" />
diff --git a/releasesteps.xml b/releasesteps.xml
new file mode 100644
index 0000000..0cc9681
--- /dev/null
+++ b/releasesteps.xml
@@ -0,0 +1,707 @@
+<?xml version="1.0"?>
+<!--
+
+  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.
+
+-->
+
+<project name="CreateCompilerReleaseCandidate" default="main" basedir=".">
+
+    <!-- use -Dtag=<tag or commit hash> to build from other than the head -->
+
+    <!-- Required for OSX 10.6 / Snow Leopard Performance. -->
+    <!-- Java 7 on Mac requires OSX 10.7.3 or higher and is 64-bit only -->
+    <!-- local.d32 is set/used in build.properties so this needs to be done first. -->
+    <condition property="local.d32" value="-d32">
+        <and>
+            <os family="windows"/>
+            <equals arg1="${sun.arch.data.model}" arg2="64"/>
+            <equals arg1="${os.arch}" arg2="x86_64"/>
+            <equals arg1="${ant.java.version}" arg2="1.6"/>
+        </and>
+    </condition>
+
+    <condition property="isMac" value="mac">
+        <os family="mac" />
+    </condition>
+    <condition property="isWindows" value="windows">
+        <os family="windows" />
+    </condition>
+    <condition property="isLinux" value="linux">
+		<and>
+			<os family="unix" />
+			<not>
+				<isset property="isMac" />
+			</not>
+		</and>
+    </condition>
+	
+	<property name="rat.report" value="${basedir}/rat-report.txt"/>
+    <property name="apache.rat.jar" value="apache-rat-0.11.jar" />
+    <property name="apache.rat.tasks.jar" value="apache-rat-tasks-0.11.jar" />
+    <property name="apache.rat.url" value="https://search.maven.org/remotecontent?filepath=org/apache/rat/apache-rat/0.11" />
+    <property name="apache.rat.tasks.url" value="https://search.maven.org/remotecontent?filepath=org/apache/rat/apache-rat-tasks/0.11" />
+    
+	<property file="${basedir}/local.properties" />
+	<property file="${basedir}/build.properties" />
+	   
+    <property environment="env"/>
+    
+	<condition property="do.copy.downloads" >
+		<isset property="download.cache.dir" /> 
+	</condition>
+	
+    <condition property="CRLF" value="%0D%0A">
+        <isset property="isWindows" />
+    </condition>
+    <property name="CRLF" value="%0A" />
+    
+    <condition property="mvn" value="mvn.cmd">
+        <isset property="isWindows" />
+    </condition>
+    <property name="mvn" value="mvn" />
+
+    <available file="${env.ANT_HOME}/lib/${apache.rat.jar}"
+        type="file"
+        property="apache.rat.found"/>
+    <available file="${env.ANT_HOME}/lib/${apache.rat.tasks.jar}"
+        type="file"
+        property="apache.rat.tasks.found"/>
+		
+    <fail message="The release version number is not set.  Specify -Drelease.version=&lt;release version (e.g. 0.9.0, 1.0.0, etc)&gt;"
+        unless="release.version"/>
+        
+	<target name="install-rat" depends="install-rat.jar,install-rat.tasks.jar" />
+	<target name="install-rat.jar" unless="apache.rat.found">
+		<get src="${apache.rat.url}/${apache.rat.jar}" dest="${env.ANT_HOME}/lib/${apache.rat.jar}" />
+	</target>
+	<target name="install-rat.tasks.jar" unless="apache.rat.tasks.found">
+		<get src="${apache.rat.url}/${apache.rat.tasks.jar}" dest="${env.ANT_HOME}/lib/${apache.rat.tasks.jar}" />
+	</target>
+	
+    <target name="rat-taskdef" description="Rat taskdef">
+        <typedef resource="org/apache/rat/anttasks/antlib.xml"
+        uri="antlib:org.apache.rat.anttasks"
+        classpathref="anttask.classpath"/>
+    </target>
+    
+    <target name="checkout_tag" if="tag" >
+        <exec executable="${git}" dir="${basedir}" failonerror="true" >
+            <arg value="checkout" />
+            <arg value="${tag}" />
+        </exec>
+    </target>
+
+    <target name="Release_Step_003" depends="get-temp-folder,download-artifacts,unzip-artifacts,build-source,validate-bits">
+    </target>
+    <target name="get-temp-folder">
+        <input
+        message="Enter a temporary folder to store the downloaded artifacts:"
+        addproperty="artifactfolder"/>
+        <mkdir dir="${artifactfolder}" />
+        <available file="${artifactfolder}"
+        type="dir"
+        property="artifact.folder.found"/>
+        <fail message="Could not create artifact folder"
+        unless="artifact.folder.found"/>
+    </target>
+    
+    <target name="download-artifacts-utils" if="utils">
+        <get src="http://apacheroyaleci.westus2.cloudapp.azure.com:8080/job/Royale_Release_Step_002a_if_utils/lastSuccessfulBuild/artifact/*zip*/archive.zip" dest="${artifactfolder}/archive_utils.zip" />
+    </target>
+    
+    <target name="download-artifacts" if="artifactfolder">
+        <antcall target="download-artifacts-utils" />
+        <get src="http://apacheroyaleci.westus2.cloudapp.azure.com:8080/job/Royale_Release_Step_003/lastSuccessfulBuild/artifact/*zip*/archive.zip" dest="${artifactfolder}/archive.zip" />
+    </target>
+
+    <target name="unzip-artifacts-utils" if="utils">
+        <mkdir dir="${artifactfolder}/artifacts" />
+        <unzip src="${artifactfolder}/archive_utils.zip" dest="${artifactfolder}/artifacts"/>
+    </target>
+    <target name="unzip-artifacts" if="artifactfolder">
+        <antcall target="unzip-artifacts-utils" />
+        <mkdir dir="${artifactfolder}/artifacts" />
+        <unzip src="${artifactfolder}/archive.zip" dest="${artifactfolder}/artifacts"/>
+    </target>
+    <target name="build-source-utils" if="utils">
+        <!-- build these modules -->
+        <exec executable="${mvn}" dir="${artifactfolder}/sources" failonerror="true" >
+            <arg value="clean" />
+            <arg value="install" />
+            <arg value="-P" />
+            <arg value="-main,utils" />
+        </exec>
+    </target>
+    <target name="build-source" >
+        <mkdir dir="${artifactfolder}/sources" />
+        <unzip src="${artifactfolder}/artifacts/archive/target/checkout/release-dir/org/apache/royale/compiler/royale-compiler-parent/${release.version}/royale-compiler-parent-${release.version}-source-release.zip" dest="${artifactfolder}/sources" >
+            <cutdirsmapper dirs="1" />
+        </unzip>
+        
+        <antcall target="build-source-utils" />
+        <!-- build these modules -->
+        <exec executable="${mvn}" dir="${artifactfolder}/sources" failonerror="true" >
+            <arg value="clean" />
+            <arg value="install" />
+        </exec>
+    </target>
+    
+    <target name="get-artifact-folder" unless="artifactfolder">
+        <input
+            message="Enter the temporary folder to store the downloaded artifacts:"
+            addproperty="artifactfolder"/>
+        <available file="${artifactfolder}"
+            type="dir"
+            property="artifact.folder.found"/>
+        <fail message="Could not find artifact folder"
+            unless="artifact.folder.found"/>
+    </target>
+    
+    <target name="get-utils-version">
+        <xmlproperty file="${artifactfolder}/sources/compiler-jburg-types/pom.xml" prefix="jburg" />
+        <property name="utils.version" value="${jburg.project.version}" />
+        <echo>utils version is ${utils.version}</echo>
+    </target>
+    
+    <target name="check-for-utils" unless="utils">
+        <available file="${artifactfolder}/sources/compiler-jburg-types/target/compiler-jburg-types-${utils.version}.jar" property="utils" value="true" />
+    </target>
+
+    <target name="validate-bits" depends="get-artifact-folder,get-utils-version,compare-jars">
+    </target>
+    
+    <target name="write-out-maven-utils-jars-list" if="utils" >
+        <delete file="${artifactfolder}/jars.txt" />
+        <!-- this is a comma-delimited, no spaces, no-line-breaks list used to decide which jars
+         to skip in the rat-check of the binaries and which jars to examine before approval -->
+        <property name="jars-list-with-utils" value="compiler-jburg-types,compiler-build-tools,${jars-list}"/>
+        <echo file="${artifactfolder}/jars.txt" message="${jars-list-with-utils}"/>
+    </target>
+    
+    <target name="write-out-maven-jars-list" >
+        <delete file="${artifactfolder}/jars.txt" />
+        <!-- this is a comma-delimited, no spaces, no-line-breaks list used to decide which jars
+         to skip in the rat-check of the binaries and which jars to examine before approval -->
+        <property name="jars-list" value="compiler,compiler-common,compiler-externc,compiler-jx,compiler-test-utils,swfutils,debugger,flex-compiler-oem,royale-ant-tasks,royale-maven-plugin"/>
+        <echo file="${artifactfolder}/jars.txt" message="${jars-list}"/>
+        <antcall target="write-out-maven-utils-jars-list" />
+    </target>
+
+    <target name="compare-jars" depends="write-out-maven-jars-list">
+        <!-- comma delimited list, no spaces, not one file per line -->
+        <copy file="${artifactfolder}/jars.txt" tofile="${artifactfolder}/loop.txt" />
+        <ant antfile="releasesteps.xml" target="loopOnce" inheritAll="false" >
+            <property name="artifactfolder" value="${artifactfolder}" />
+            <property name="release.version" value="${release.version}" />
+            <property name="utils.version" value="${utils.version}" />
+        </ant>
+    </target>
+    
+    <target name="get-jar-version" >
+        <condition property="jar.version" value="${utils.version}"
+            else="${release.version}">
+            <or>
+                <equals arg1="${thisFile}" arg2="compiler-jburg-types" />
+                <equals arg1="${thisFile}" arg2="compiler-build-tools" />
+            </or>
+        </condition>
+    </target>
+    
+    <target name="loopOnce" >
+        <!-- make a copy of the list so we can munge it to
+         get the first item in the list -->
+        <delete file="${artifactfolder}/loop1.txt" />
+        <copy file="${artifactfolder}/loop.txt" tofile="${artifactfolder}/loop1.txt" />
+        <loadfile srcFile="${artifactfolder}/loop.txt" property="checkiflast" />
+        <condition property="islast" value="true">
+            <not>
+                <contains string="${checkiflast}" substring="," />
+            </not>
+        </condition>
+        <antcall target="notlast" />
+        <antcall target="lastone" />
+    </target>
+    <target name="notlast" unless="islast">
+        <loadfile srcFile="${artifactfolder}/loop1.txt" property="echoFile" />
+        <replaceregexp file="${artifactfolder}/loop1.txt" match="^(.*),(.*)" replace="\2" />
+        <loadfile srcFile="${artifactfolder}/loop1.txt" property="thisFile" />
+        <antcall target="compare_files" />
+        <replaceregexp file="${artifactfolder}/loop.txt" match="^(.*),(.*)" replace="\1" />
+        <ant antfile="releasesteps.xml" target="loopOnce" inheritAll="false">
+            <property name="artifactfolder" value="${artifactfolder}" />
+            <property name="release.version" value="${release.version}" />
+            <property name="utils.version" value="${utils.version}" />
+        </ant>
+    </target>
+    <target name="lastone" if="islast">
+        <loadfile srcFile="${artifactfolder}/loop1.txt" property="thisFile" />
+        <antcall target="compare_files" />
+        <delete file="${artifactfolder}/loop.txt" />
+        <delete file="${artifactfolder}/loop1.txt" />
+    </target>
+
+    <target name="compare_files" depends="get-jar-version">
+        <echo>comparing ${thisFile}-${jar.version}</echo>
+        <fail message="${artifactfolder}/artifacts/archive/target/checkout/release-dir/org/apache/royale/compiler/${thisFile}/${jar.version}/${thisFile}-${jar.version}.jar does not exist" >
+            <condition>
+                <not>
+                    <resourceexists><file file="${artifactfolder}/artifacts/archive/target/checkout/release-dir/org/apache/royale/compiler/${thisFile}/${jar.version}/${thisFile}-${jar.version}.jar"/></resourceexists>
+                </not>
+            </condition>
+        </fail>
+        <fail message="${artifactfolder}/sources/${thisFile}/target/${thisFile}-${jar.version}.jar does not exist" >
+            <condition>
+                <not>
+                    <resourceexists><file file="${artifactfolder}/sources/${thisFile}/target/${thisFile}-${jar.version}.jar"/></resourceexists>
+                </not>
+            </condition>
+        </fail>
+        <condition property="filesmatch" value="true">
+              <filesmatch file1="${artifactfolder}/artifacts/archive/target/checkout/release-dir/org/apache/royale/compiler/${thisFile}/${jar.version}/${thisFile}-${jar.version}.jar"
+                file2="${artifactfolder}/sources/${thisFile}/target/${thisFile}-${jar.version}.jar" />
+        </condition>
+        <fail message="${thisFile}-${jar.version}.jar does not match" unless="filesmatch" />
+    </target>
+    
+    <target name="Release_Step_003_Sign" depends="get-artifact-folder">
+        <fail message="release.version not specified"
+            unless="release.version"/>
+        <antcall target="sign-file" >
+            <param name="file" value="${artifactfolder}/artifacts/archive/target/checkout/release-dir/org/apache/royale/compiler/royale-compiler-parent/${release.version}/royale-compiler-parent-${release.version}-source-release.zip" />
+        </antcall>
+        <antcall target="sign-file" >
+            <param name="file" value="${artifactfolder}/artifacts/archive/target/checkout/release-dir/org/apache/royale/compiler/royale-compiler-parent/${release.version}/royale-compiler-parent-${release.version}.pom" />
+        </antcall>
+        <antcall target="sign-jar-artifacts" >
+            <param name="jarname" value="compiler" />
+        </antcall>
+        <antcall target="sign-jar-artifacts" >
+            <param name="jarname" value="compiler-common" />
+        </antcall>
+        <antcall target="sign-jar-artifacts" >
+            <param name="jarname" value="compiler-externc" />
+        </antcall>
+        <antcall target="sign-file" >
+            <param name="file" value="${artifactfolder}/artifacts/archive/target/checkout/release-dir/org/apache/royale/compiler/compiler-externc/${release.version}/compiler-externc-${release.version}-tests.jar" />
+        </antcall>
+        <antcall target="sign-jar-artifacts" >
+            <param name="jarname" value="compiler-jx" />
+        </antcall>
+        <antcall target="sign-jar-artifacts" >
+            <param name="jarname" value="compiler-test-utils" />
+        </antcall>
+        <antcall target="sign-jar-artifacts" >
+            <param name="jarname" value="debugger" />
+        </antcall>
+        <antcall target="sign-jar-artifacts" >
+            <param name="jarname" value="flex-compiler-oem" />
+        </antcall>
+        <antcall target="sign-jar-artifacts" >
+            <param name="jarname" value="royale-ant-tasks" />
+        </antcall>
+        <antcall target="sign-jar-artifacts" >
+            <param name="jarname" value="royale-maven-plugin" />
+        </antcall>
+		 <antcall target="sign-jar-artifacts">
+            <param name="jarname" value="royaleunit-ant-tasks" />
+        </antcall>
+        <antcall target="sign-jar-artifacts" >
+            <param name="jarname" value="swfutils" />
+        </antcall>
+        <antcall target="sign-utils" />
+    </target>
+
+    <target name="sign-utils" depends="get-utils-version,check-for-utils" if="utils">
+        <antcall target="sign-utils-jar-artifacts" >
+            <param name="jarname" value="compiler-build-tools" />
+        </antcall>
+        <antcall target="sign-utils-jar-artifacts" >
+            <param name="jarname" value="compiler-jburg-types" />
+        </antcall>
+    </target>
+
+    <target name="sign-jar-artifacts">
+        <antcall target="sign-file" >
+            <param name="file" value="${artifactfolder}/artifacts/archive/target/checkout/release-dir/org/apache/royale/compiler/${jarname}/${release.version}/${jarname}-${release.version}.pom" />
+        </antcall>
+        <antcall target="sign-file" >
+            <param name="file" value="${artifactfolder}/artifacts/archive/target/checkout/release-dir/org/apache/royale/compiler/${jarname}/${release.version}/${jarname}-${release.version}-javadoc.jar" />
+        </antcall>
+        <antcall target="sign-file" >
+            <param name="file" value="${artifactfolder}/artifacts/archive/target/checkout/release-dir/org/apache/royale/compiler/${jarname}/${release.version}/${jarname}-${release.version}-sources.jar" />
+        </antcall>
+        <antcall target="sign-file" >
+            <param name="file" value="${artifactfolder}/artifacts/archive/target/checkout/release-dir/org/apache/royale/compiler/${jarname}/${release.version}/${jarname}-${release.version}.jar" />
+        </antcall>
+    </target>
+    
+    <target name="sign-utils-jar-artifacts">
+        <antcall target="sign-file" >
+            <param name="file" value="${artifactfolder}/artifacts/archive/target/checkout/release-dir/org/apache/royale/compiler/${jarname}/${utils.version}/${jarname}-${utils.version}.pom" />
+        </antcall>
+        <antcall target="sign-file" >
+            <param name="file" value="${artifactfolder}/artifacts/archive/target/checkout/release-dir/org/apache/royale/compiler/${jarname}/${utils.version}/${jarname}-${utils.version}-javadoc.jar" />
+        </antcall>
+        <antcall target="sign-file" >
+            <param name="file" value="${artifactfolder}/artifacts/archive/target/checkout/release-dir/org/apache/royale/compiler/${jarname}/${utils.version}/${jarname}-${utils.version}-sources.jar" />
+        </antcall>
+        <antcall target="sign-file" >
+            <param name="file" value="${artifactfolder}/artifacts/archive/target/checkout/release-dir/org/apache/royale/compiler/${jarname}/${utils.version}/${jarname}-${utils.version}.jar" />
+        </antcall>
+    </target>
+    
+    
+    <target name="sign-file">
+        <exec executable="gpg">
+            <arg value="--armor" />
+            <arg value="--output" />
+            <arg value="${file}.asc" />
+            <arg value="--detach-sig" />
+            <arg value="${file}" />
+        </exec>
+    </target>
+    
+    <target name="Release_Step_003_Upload" depends="get-artifact-folder">
+        <fail message="release.version not specified"
+            unless="release.version"/>
+        <exec executable="${mvn}" dir="${artifactfolder}/sources" failonerror="true" >
+            <arg value="wagon:upload" />
+            <arg value="-X" />
+            <arg value="-Dwagon.fromDir=${artifactfolder}/artifacts/archive/target/checkout/release-dir" />
+            <arg value="-P" />
+            <arg value="upload-release-to-staging,-main" />
+        </exec>
+    </target>
+    
+    <target name="main" depends="install-rat,credentials" description="Perform required release approval steps">
+		<antcall target="check-new-version" />
+		<exec executable="${git}" dir="${basedir}" failonerror="true" >
+			<arg value="pull" />
+			<arg value="--rebase" />
+		</exec>
+        <antcall target="checkout_tag" />
+		<ant antfile="build.xml" target="release" />
+		<ant antfile="build.xml" target="create-md5" />
+		<ant antfile="build.xml" target="sign" />
+		<mkdir dir="${dist.dev}/royale/compiler/${release.version}/rc${rc}/binaries" />
+		<copy todir="${dist.dev}/royale/compiler/${release.version}/rc${rc}" >
+			<fileset dir="${basedir}/out" >
+				<include name="apache-royale-compiler-${release.version}-src*" />
+			</fileset>
+		</copy>
+		<copy todir="${dist.dev}/royale/compiler/${release.version}/rc${rc}/binaries" >
+			<fileset dir="${basedir}/out" >
+				<include name="apache-royale-compiler-${release.version}-bin*" />
+			</fileset>
+		</copy>
+		<copy file="${basedir}/README" tofile="${dist.dev}/royale/compiler/${release.version}/rc${rc}/READme" />
+		<copy file="${basedir}/ApproveCompiler.xml" tofile="${dist.dev}/royale/compiler/${release.version}/rc${rc}/ApproveCompiler.xml" />
+		<copy file="${basedir}/apache-royale-compiler-installer-config.xml" tofile="${dist.dev}/royale/compiler/${release.version}/rc${rc}/binaries/apache-royale-compiler-installer-config.xml" />
+        <exec executable="${svn}" dir="${dist.dev}/royale/compiler" failonerror="true" >
+            <arg value="update" />
+        </exec>
+		<exec executable="${svn}" dir="${dist.dev}/royale/compiler" failonerror="true" >
+			<arg value="add" />
+			<arg value="${dist.dev}/royale/compiler/${release.version}/rc${rc}" />
+		</exec>
+		<exec executable="${svn}" dir="${dist.dev}/royale/compiler" failonerror="true" >
+			<arg value="commit" />
+			<arg value="--username" />
+			<arg value="${apache.username}" />
+			<arg value="--password" />
+			<arg value="${apache.password}" />
+			<arg value="-m" />
+			<arg value="rc${rc} of Apache Royale Compiler ${release.version}" />
+		</exec>
+        <antcall target="tag_release" />
+		<antcall target="update-installer-config" />
+		<antcall target="mail" />
+    </target>
+    
+    <target name="tag_release" unless="tag" >
+        <exec executable="${git}" dir="${basedir}" failonerror="true" >
+            <arg value="tag" />
+            <arg value="-a" />
+            <arg value="apache-royale-compiler-${release.version}-rc${rc}" />
+            <arg value="-m" />
+            <arg value="&quot;rc${rc} of apache-royale-compiler-${release.version}&quot;" />
+        </exec>
+        <exec executable="${git}" dir="${basedir}" failonerror="true" >
+            <arg value="push" />
+            <arg value="--tags" />
+        </exec>
+    </target>
+
+	<target name="credentials" depends="get-username,get-password">
+		<echo>${apache.username}</echo>
+		<echo>${apache.password}</echo>
+	</target>
+	<target name="get-username" unless="apache.username" >
+        <input
+        message="Enter Apache account username:"
+        addproperty="apache.username"/>
+        <condition property="have.username">
+			<not>
+				<equals trim="true" arg1="" arg2="${apache.username}"/>
+			</not>
+        </condition>
+		<fail message="The apache.username property is not set.  It should be the username for Apache SVN and Git."
+			unless="have.username"/>
+	</target>
+	<target name="get-password" unless="apache.password" >
+        <input
+        message="Enter Apache account password:"
+        addproperty="apache.password"/>
+        <condition property="have.password">
+			<not>
+				<equals trim="true" arg1="" arg2="${apache.password}"/>
+			</not>
+        </condition>
+		<fail message="The apache.password property is not set.  It should be the password for Apache SVN and Git."
+			unless="have.password"/>
+	</target>
+	
+	<target name="update-installer-config" >
+		<exec executable="${svn}" dir="${site}" failonerror="true" >
+			<arg value="update" />
+			<arg value="trunk/content/installer/sdk-installer-config-4.0.xml" />
+		</exec>
+        <replaceregexp byline="true">
+            <regexp pattern="developmentVersion=&quot;${release.version}&quot; rc=&quot;rc.*&quot; latestVersion"/>
+            <substitution expression="developmentVersion=&quot;${release.version}&quot; rc=&quot;rc${rc}&quot; latestVersion"/>
+            <fileset dir="${site}/trunk/content/installer">
+                <include name="sdk-installer-config-4.0.xml"/>
+            </fileset>
+        </replaceregexp>
+		<exec executable="${svn}" dir="${site}" failonerror="true" >
+			<arg value="commit" />
+			<arg value="--username" />
+			<arg value="${apache.username}" />
+			<arg value="--password" />
+			<arg value="${apache.password}" />
+			<arg value="-m" />
+			<arg value="&quot;update sdk-installer-config-4.0 for Compiler ${release.version} rc${rc}&quot;" />
+		</exec>
+		<!-- pause to give buildbot chance to react -->
+		<sleep seconds="5" />
+		<get src="https://cms.apache.org/royale/publish" username="${apache.username}" password="${apache.password}" dest="${basedir}/getresult.txt" />
+		<delete file="${basedir}/getresult.txt" />
+	</target>
+
+	<target name="update-installer-config-release" depends="credentials">
+		<exec executable="${svn}" dir="${site}" failonerror="true" >
+			<arg value="update" />
+			<arg value="trunk/content/installer/sdk-installer-config-4.0.xml" />
+		</exec>
+        <xmlproperty file="${site}/trunk/content/installer/sdk-installer-config-4.0.xml" semanticAttributes="true" collapseAttributes="true"/>
+		<property name="latest.release" value="${config.products.ApacheRoyaleCompiler.latestVersion}" />
+        <replaceregexp byline="true" flags="g">
+            <regexp pattern="ApacheRoyaleCompiler(.*)latestVersion=&quot;${latest.release}&quot;(.*)"/>
+            <substitution expression="ApacheRoyaleCompiler\1latestVersion=&quot;${release.version}&quot;\2"/>
+            <fileset dir="${site}/trunk/content/installer">
+                <include name="sdk-installer-config-4.0.xml"/>
+            </fileset>
+        </replaceregexp>
+		<exec executable="${svn}" dir="${site}" failonerror="true" >
+			<arg value="commit" />
+			<arg value="--username" />
+			<arg value="${apache.username}" />
+			<arg value="--password" />
+			<arg value="${apache.password}" />
+			<arg value="-m" />
+			<arg value="&quot;update sdk-installer-config-4.0 and other files for royale sdk ${release.version} rc${rc}&quot;" />
+		</exec>
+		<!-- pause to give buildbot chance to react -->
+		<sleep seconds="5" />
+		<get src="https://cms.apache.org/royale/publish" username="${apache.username}" password="${apache.password}" dest="${basedir}/getresult.txt" />
+		<delete file="${basedir}/getresult.txt" />
+	</target>
+	
+	<target name="check-new-version" description="check if svn folder needs to be added" >
+		<condition property="version.folder" value="${dist.dev}/royale/compiler/${release.version}" >
+			<not>
+				<available file="${dist.dev}/royale/compiler/${release.version}" />
+			</not>
+		</condition>
+		<antcall target="add-version-folder" />
+	</target>
+    
+	<target name="add-version-folder" description="adds svn folder if needed" if="version.folder" >
+		<mkdir dir="${version.folder}" />
+		<exec executable="${svn}" dir="${dist.dev}/royale/compiler" failonerror="true" >
+			<arg value="add" />
+			<arg value="${version.folder}" />
+		</exec>
+	</target>
+		
+    <target name="mail" >
+        <!-- try to set line breaks before the vertical line            | -->
+        <echo file="${basedir}/discussthread.properties">discuss.thread.body=This is the discussion thread.\n\
+\n\
+Changes in this RC include:\n\
+\n\
+\n\
+Thanks,\n\
+${my.name}
+</echo>
+        <replace file="${basedir}/discussthread.properties">
+            <replacefilter token=" " value="%20" />
+            <replacefilter token="\n" value="${CRLF}" />
+        </replace>
+        <property file="${basedir}/discussthread.properties" />
+
+        <!-- try to set line breaks before the vertical line            | -->
+        <echo file="${basedir}/votethread.properties">vote.thread.body=Hi,\n\
+\n\
+This is vote for the ${release.version} release of the Royale\n\
+compilers.  The only purpose of the Compiler packages are to serve as\n\
+upstream packages for the Royale release.\n\
+\n\
+The release candidate can be found here;\n\
+https://dist.apache.org/repos/dist/dev/royale/compiler/${release.version}/rc${rc}/\n\
+\n\
+Before voting please review the section, 'What are the ASF requirements on\n\
+approving a release?', at:\n\
+http://www.apache.org/dev/release.html#approving-a-release\n\
+\n\
+At a minimum you would be expected to check that:\n\
+- MD5 and signed packages are correct\n\
+- README, RELEASE_NOTES, NOTICE and LICENSE files are all fine\n\
+- That the build script completes successfully\n\
+- That you can compile using the results of building the source package\n\
+\n\
+The source package is set up the same way as the repo.  This means that\n\
+the results of the build are not the same as the binary package.  The\n\
+compiled source package can be used to build Royale apps via the command\n\
+line and Ant, but not in Flash Builder or other IDEs.  You can test the source\n\
+package by building it, then pointing to it from the source package of the\n\
+Royale release candidate and building the examples in the Royale package.\n\
+\n\
+The binary package is set up as an upstream package for the Royale\n\
+release.  The most convenient way to use the binary package is to install\n\
+a Royale SDK via Ant or the Installer.\n\
+\n\
+Please vote to approve this release:\n\
++1 Approve the release\n\
+-1 Disapprove the release (please provide specific comments to why)\n\
+\n\
+This vote will be open for 72 hours or until a result can be called.\n\
+\n\
+The vote passes if there is:\n\
+- At least 3 +1 votes from the PMC\n\
+- More positive votes than negative votes\n\
+\n\
+Remember that this is a 'beta-quality' release so there\n\
+will be many bugs found.  The goal is not to try to find and fix bugs\n\
+in the RC, but to make sure we have the packaging right, and enough\n\
+functionality that folks will have some success trying to use it.\n\
+\n\
+People who are not in PMC are also encouraged to test out the release and\n\
+vote, although their votes will not be binding, they can influence how the\n\
+PMC votes.\n\
+\n\
+When voting please indicate what OS, IDE, Flash Player version and AIR\n\
+version you tested with.\n\
+\n\
+Please put all discussion about this release in the DISCUSSION thread not\n\
+this VOTE thread.\n\
+\n\
+For your convenience there is an ant script that automates the common\n\
+steps to validate a release.  Instead of individually downloading the\n\
+package and signature files, unzipping, etc, you can instead:\n\
+1) create an empty folder,\n\
+2) download into that folder this file:\n\
+https://dist.apache.org/repos/dist/dev/royale/compiler/${release.version}/rc${rc}/ApproveCompiler.xml\n\
+3) run the script:\n\
+   ant -e -f ApproveCompiler.xml -Drelease.version=${release.version} -Drc=${rc}\n\
+\n\
+You are not required to use this script, and more testing of the packages\n\
+and build results are always encouraged.\n\
+\n\
+Thanks,\n\
+${my.name}
+</echo>
+        <replace file="${basedir}/votethread.properties">
+            <replacefilter token=" " value="%20" />
+            <replacefilter token="\n" value="${CRLF}" />
+        </replace>
+        <property file="${basedir}/votethread.properties" />
+        <echo file="${basedir}/votethread.html">&lt;html&gt;&lt;body&gt;&lt;a href=&quot;mailto:dev@royale.apache.org?subject=[DISCUSS]%20Discuss%20Release%20Apache%20Royale%20Compiler%20${release.version}%20RC${rc}&amp;body=${discuss.thread.body}&quot;&gt;Click here to review discuss thread&lt;/a&gt;&lt;br/&gt;&lt;a href=&quot;mailto:dev@royale.apache.org?subject=[VOTE]%20Release%20Apache%20Royale%20Compiler%20${release.version}%20RC${rc}&amp;body=${vote.thread.body}&quot;&gt;Click here to review vote thread&lt;/a&gt;&lt;/body&gt;&lt;/html&gt;</echo>
+        <makeurl file="${basedir}/votethread.html" property="vote.thread.url" />
+        <exec executable="${browser}">
+            <arg value="${vote.thread.url}" />
+        </exec>
+		<delete file="${basedir}/votethread.properties" />
+		<delete file="${basedir}/votethread.html" />
+		<delete file="${basedir}/discussthread.properties" />
+    </target>
+
+	<target name="release" depends="credentials" >
+		<available file="${svn.dist.release}"
+			type="dir" 
+			property="dist.release" value="${svn.dist.release}" />
+    
+		<fail message="The svn.dist.release property is not set to the working copy for https://dist.apache.org/repos/dist/release."
+			unless="dist.release"/>
+				
+		<exec executable="${svn}" dir="${dist.release}/royale" failonerror="true" >
+			<arg value="update" />
+		</exec>
+		<exec executable="${svn}" dir="${dist.release}/royale/compiler" failonerror="true" >
+			<arg value="mv" />
+			<arg value="${dist.dev}/royale/compiler/${release.version}/rc${rc}" />
+            <arg value="${dist.release}/royale/compiler/${release.version}" />
+		</exec>
+		<exec executable="${svn}" dir="${dist.release}/.." failonerror="true" >
+			<arg value="commit" />
+			<arg value="--username" />
+			<arg value="${apache.username}" />
+			<arg value="--password" />
+			<arg value="${apache.password}" />
+			<arg value="-m" />
+			<arg value="Apache Royale Compiler ${release.version}" />
+		</exec>
+        <antcall target="release.tag" />
+		<exec executable="${git}" dir="${basedir}" failonerror="true" >
+			<arg value="push" />
+			<arg value="--tags" />
+		</exec>
+		<echo>Wait at least 24 hours before running update-installer-config-release target</echo>
+	</target>
+	
+    <target name="release.tag" >
+        <condition property="tag" value="apache-royale-compiler-${release.version}-rc${rc}">
+            <not>
+                <isset property="tag" />
+            </not>
+        </condition>
+        <exec executable="${git}" dir="${basedir}" failonerror="true" output="${basedir}/taghash.txt">
+            <arg value="show" />
+            <arg value="${tag}" />
+        </exec>
+        <replaceregexp file="${basedir}/taghash.txt" match="(.*).commit (.*).Author(.*)" replace="\2" byline="false" flags="s" />
+        <loadfile srcFile="${basedir}/taghash.txt" property="releasehash" />
+        <exec executable="${git}" dir="${basedir}" failonerror="true" >
+            <arg value="tag" />
+            <arg value="-a" />
+            <arg value="apache-royale-compiler-${release.version}" />
+            <arg value="${releasehash}" />
+            <arg value="-m" />
+            <arg value="&quot;Official release of apache-royale-compiler-${release.version}&quot;" />
+        </exec>
+    </target>
+</project>
diff --git a/royale-ant-tasks/pom.xml b/royale-ant-tasks/pom.xml
index ba50956..b15f4d0 100644
--- a/royale-ant-tasks/pom.xml
+++ b/royale-ant-tasks/pom.xml
@@ -1,42 +1,52 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.apache.royale.compiler</groupId>
-    <artifactId>royale-compiler-parent</artifactId>
-    <version>0.9.4</version>
-  </parent>
-
-  <artifactId>royale-ant-tasks</artifactId>
-  <version>0.9.4</version>
-
-  <name>Apache Royale: Royale Ant Tasks</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.ant</groupId>
-      <artifactId>ant</artifactId>
-      <version>1.7.0</version>
-    </dependency>
-  </dependencies>
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+

+  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.

+

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+  <modelVersion>4.0.0</modelVersion>

+

+  <parent>

+    <groupId>org.apache.royale.compiler</groupId>

+    <artifactId>royale-compiler-parent</artifactId>

+    <version>0.9.6</version>

+  </parent>

+

+  <artifactId>royale-ant-tasks</artifactId>

+  <version>0.9.6</version>

+

+  <name>Apache Royale: Royale Ant Tasks</name>

+

+  <build>

+    <plugins>

+        <plugin>

+            <groupId>io.github.zlika</groupId>

+            <artifactId>reproducible-build-maven-plugin</artifactId>

+            <version>0.9</version>

+        </plugin>

+    </plugins>

+  </build>

+

+  <dependencies>

+    <dependency>

+      <groupId>org.apache.ant</groupId>

+      <artifactId>ant</artifactId>

+      <version>1.7.0</version>

+    </dependency>

+  </dependencies>

+

+</project>

diff --git a/royale-ant-tasks/src/main/java/org/apache/royale/compiler/ant/FlexTask.java b/royale-ant-tasks/src/main/java/org/apache/royale/compiler/ant/FlexTask.java
index 79f7060..40e119f 100644
--- a/royale-ant-tasks/src/main/java/org/apache/royale/compiler/ant/FlexTask.java
+++ b/royale-ant-tasks/src/main/java/org/apache/royale/compiler/ant/FlexTask.java
@@ -308,9 +308,9 @@
 
             try
             {
-                Method toolMethod = toolClass.getMethod(toolMethodName, new Class[] {String[].class});
+                Method toolMethod = toolClass.getMethod(toolMethodName, String[].class);
                 Object result = toolMethod.invoke(null, new Object[] {cmdline.getArguments()});
-                exitCode = ((Integer)result).intValue();
+                exitCode = ((Integer)result);
             }
             catch (Exception e)
             {
@@ -337,9 +337,9 @@
     	
     	try
     	{
-			Method toolFailureMethod = toolClass.getMethod(toolFailureMethodName, new Class[] {int.class});
-			Object result = toolFailureMethod.invoke(null, new Object[] {exitCode});
-			fatal = ((Boolean)result).booleanValue();
+			Method toolFailureMethod = toolClass.getMethod(toolFailureMethodName, int.class);
+			Object result = toolFailureMethod.invoke(null, exitCode);
+			fatal = ((Boolean)result);
 		}
     	catch (Exception e)
     	{
diff --git a/royale-maven-plugin/pom.xml b/royale-maven-plugin/pom.xml
index e94aa2e..31e6e98 100644
--- a/royale-maven-plugin/pom.xml
+++ b/royale-maven-plugin/pom.xml
@@ -1,135 +1,140 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.apache.royale.compiler</groupId>
-    <artifactId>royale-compiler-parent</artifactId>
-    <version>0.9.4</version>
-  </parent>
-
-  <artifactId>royale-maven-plugin</artifactId>
-  <version>0.9.4</version>
-  <packaging>maven-plugin</packaging>
-
-  <name>Apache Royale: Royale Maven Plugin</name>
-
-  <properties>
-    <maven.version>3.3.1</maven.version>
-  </properties>
-
-  <dependencies>
-    <dependency>
-      <groupId>javax.inject</groupId>
-      <artifactId>javax.inject</artifactId>
-      <version>1</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-plugin-api</artifactId>
-      <version>${maven.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven.plugin-tools</groupId>
-      <artifactId>maven-plugin-annotations</artifactId>
-      <version>3.4</version>
-      <scope>provided</scope>
-    </dependency>
-
-    <!-- Apache Velocity templating engine for generating config files -->
-    <dependency>
-      <groupId>org.apache.velocity</groupId>
-      <artifactId>velocity</artifactId>
-      <version>1.7</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-project</artifactId>
-      <version>2.2.1</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-core</artifactId>
-      <version>${maven.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven.shared</groupId>
-      <artifactId>file-management</artifactId>
-      <version>3.0.0</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-      <version>2.4</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-lang3</artifactId>
-      <version>3.4</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.flex</groupId>
-      <artifactId>flex-tool-api</artifactId>
-      <version>1.0.0</version>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-plugin-plugin</artifactId>
-        <version>3.4</version>
-        <configuration>
-          <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
-        </configuration>
-        <executions>
-          <execution>
-            <id>mojo-descriptor</id>
-            <goals>
-              <goal>descriptor</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>help-goal</id>
-            <goals>
-              <goal>helpmojo</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.sonatype.plugins</groupId>
-        <artifactId>sisu-maven-plugin</artifactId>
-        <version>1.1</version>
-        <executions>
-          <execution>
-            <id>generate-index</id>
-            <goals>
-              <goal>main-index</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+

+  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.

+

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+  <modelVersion>4.0.0</modelVersion>

+

+  <parent>

+    <groupId>org.apache.royale.compiler</groupId>

+    <artifactId>royale-compiler-parent</artifactId>

+    <version>0.9.6</version>

+  </parent>

+

+  <artifactId>royale-maven-plugin</artifactId>

+  <version>0.9.6</version>

+  <packaging>maven-plugin</packaging>

+

+  <name>Apache Royale: Royale Maven Plugin</name>

+

+  <properties>

+    <maven.version>3.3.1</maven.version>

+  </properties>

+

+  <dependencies>

+    <dependency>

+      <groupId>javax.inject</groupId>

+      <artifactId>javax.inject</artifactId>

+      <version>1</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.maven</groupId>

+      <artifactId>maven-plugin-api</artifactId>

+      <version>${maven.version}</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.maven.plugin-tools</groupId>

+      <artifactId>maven-plugin-annotations</artifactId>

+      <version>3.4</version>

+      <scope>provided</scope>

+    </dependency>

+

+    <!-- Apache Velocity templating engine for generating config files -->

+    <dependency>

+      <groupId>org.apache.velocity</groupId>

+      <artifactId>velocity</artifactId>

+      <version>1.7</version>

+    </dependency>

+

+    <dependency>

+      <groupId>org.apache.maven</groupId>

+      <artifactId>maven-project</artifactId>

+      <version>2.2.1</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.maven</groupId>

+      <artifactId>maven-core</artifactId>

+      <version>${maven.version}</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.maven.shared</groupId>

+      <artifactId>file-management</artifactId>

+      <version>3.0.0</version>

+    </dependency>

+    <dependency>

+      <groupId>commons-io</groupId>

+      <artifactId>commons-io</artifactId>

+      <version>2.4</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.commons</groupId>

+      <artifactId>commons-lang3</artifactId>

+      <version>3.4</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.flex</groupId>

+      <artifactId>flex-tool-api</artifactId>

+      <version>1.0.0</version>

+    </dependency>

+  </dependencies>

+

+  <build>

+    <plugins>

+      <plugin>

+        <groupId>io.github.zlika</groupId>

+        <artifactId>reproducible-build-maven-plugin</artifactId>

+        <version>0.9</version>

+      </plugin>

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-plugin-plugin</artifactId>

+        <version>3.4</version>

+        <configuration>

+          <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>

+        </configuration>

+        <executions>

+          <execution>

+            <id>mojo-descriptor</id>

+            <goals>

+              <goal>descriptor</goal>

+            </goals>

+          </execution>

+          <execution>

+            <id>help-goal</id>

+            <goals>

+              <goal>helpmojo</goal>

+            </goals>

+          </execution>

+        </executions>

+      </plugin>

+      <plugin>

+        <groupId>org.sonatype.plugins</groupId>

+        <artifactId>sisu-maven-plugin</artifactId>

+        <version>1.1</version>

+        <executions>

+          <execution>

+            <id>generate-index</id>

+            <goals>

+              <goal>main-index</goal>

+            </goals>

+          </execution>

+        </executions>

+      </plugin>

+    </plugins>

+  </build>

+</project>

diff --git a/royale-maven-plugin/src/main/java/org/apache/royale/maven/BaseMojo.java b/royale-maven-plugin/src/main/java/org/apache/royale/maven/BaseMojo.java
index 74af100..c4c91c2 100644
--- a/royale-maven-plugin/src/main/java/org/apache/royale/maven/BaseMojo.java
+++ b/royale-maven-plugin/src/main/java/org/apache/royale/maven/BaseMojo.java
@@ -236,16 +236,22 @@
         List<String> args = new LinkedList<String>();
         args.add("-load-config=" + configFile.getPath());
         if(additionalCompilerOptions != null) {
+            if (additionalCompilerOptions.contains("\n")) {
+                additionalCompilerOptions = additionalCompilerOptions.replace("\n", "");
+            }
             if (additionalCompilerOptions.contains(";"))
             {
                 String[] options = additionalCompilerOptions.split(";");
                 for (String option : options)
                 {
-                    args.add(option);
+                    if (option.trim().length() > 0)
+                        args.add(option.trim());
                 }
             }
-            else
-                args.add(additionalCompilerOptions);
+            else {
+                if (additionalCompilerOptions.trim().length() > 0)
+                    args.add(additionalCompilerOptions.trim());
+            }
         }
         return args;
     }
@@ -331,11 +337,17 @@
     }
 
     protected List<Artifact> getJSLibraries(List<Artifact> artifacts) {
-        return internalGetLibrariesJS(artifacts);
+        if(!isForceSwcExternalLibraryPath()) {
+            return internalGetLibrariesJS(artifacts);
+        }
+        return Collections.emptyList();
     }
     
     protected List<Artifact> getSWFLibraries(List<Artifact> artifacts) {
-        return internalGetLibrariesSWF(artifacts);
+        if(!isForceSwcExternalLibraryPath()) {
+            return internalGetLibrariesSWF(artifacts);
+        }
+        return Collections.emptyList();
     }
     
     protected List<Artifact> getThemeLibraries(List<Artifact> artifacts) {
@@ -374,6 +386,9 @@
                 }
             }
         }
+        if(isForceSwcExternalLibraryPath()) {
+            externalLibraries.addAll(internalGetLibrariesJS(artifacts));
+        }
         return externalLibraries;
     }
     
@@ -387,6 +402,9 @@
                 }
             }
         }
+        if(isForceSwcExternalLibraryPath()) {
+            externalLibraries.addAll(internalGetLibrariesSWF(artifacts));
+        }
         return externalLibraries;
     }
     
diff --git a/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileASDocMojo.java b/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileASDocMojo.java
index e2da7dd..5554304 100644
--- a/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileASDocMojo.java
+++ b/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileASDocMojo.java
@@ -37,6 +37,9 @@
     @Parameter(defaultValue = "false")
     private boolean skipASDoc;
 
+    @Parameter(defaultValue = "false")
+    private boolean skipAS;
+    
     private ThreadLocal<Type> type = new ThreadLocal<Type>();
 
     @Override
@@ -90,17 +93,20 @@
         // compiler will be instantiated in the future. This method is safe in
         // any way it could be used (Multiple executions in parallel with Maven).
         try {
-            // Execute the ASDoc generation for SWF
-            getLog().info("Generating SWF apidocs");
-            type.set(Type.SWF);
-            File outputDirectory = getOutput();
-            if (!outputDirectory.exists()) {
-                if (!outputDirectory.mkdirs()) {
-                    throw new MojoExecutionException("Could not create output directory for apidocs " + outputDirectory.getPath());
+            if (!skipAS)
+            {
+                // Execute the ASDoc generation for SWF
+                getLog().info("Generating SWF apidocs");
+                type.set(Type.SWF);
+                File outputDirectory = getOutput();
+                if (!outputDirectory.exists()) {
+                    if (!outputDirectory.mkdirs()) {
+                        throw new MojoExecutionException("Could not create output directory for apidocs " + outputDirectory.getPath());
+                    }
                 }
+                super.execute();
+                getLog().info("Finished");
             }
-            super.execute();
-            getLog().info("Finished");
 
             // Execute the ASDoc generation for JavaScript
             getLog().info("Generating JS apidocs");
diff --git a/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileASMojo.java b/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileASMojo.java
index 8f549d5..05c4212 100644
--- a/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileASMojo.java
+++ b/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileASMojo.java
@@ -124,7 +124,7 @@
     @Override
     protected boolean includeLibrary(Artifact library) {
         String classifier = library.getClassifier();
-        return (classifier == null) && !("provided".equalsIgnoreCase(library.getScope()));
+        return (classifier == null) && !("runtime".equalsIgnoreCase(library.getScope()));
     }
     
     @Override
@@ -138,7 +138,7 @@
     protected boolean includeLibrarySWF(Artifact library) {
         String classifier = library.getClassifier();
         return "swf".equalsIgnoreCase(classifier) ||
-        ((classifier == null) && "provided".equalsIgnoreCase(library.getScope()));
+        ((classifier == null) && "runtime".equalsIgnoreCase(library.getScope()));
     }
 
 }
diff --git a/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileAppMojo.java b/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileAppMojo.java
index 7ddfd39..bfc40aa 100644
--- a/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileAppMojo.java
+++ b/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileAppMojo.java
@@ -170,7 +170,7 @@
     @Override
     protected boolean includeLibrary(Artifact library) {
         String classifier = library.getClassifier();
-        return (classifier == null) && !("provided".equalsIgnoreCase(library.getScope()));
+        return (classifier == null) && !("runtime".equalsIgnoreCase(library.getScope()));
     }
 
     @Override
@@ -186,7 +186,7 @@
     protected boolean includeLibrarySWF(Artifact library) {
         String classifier = library.getClassifier();
         return "swf".equalsIgnoreCase(classifier) ||
-            ((classifier == null) && "provided".equalsIgnoreCase(library.getScope()));
+            ((classifier == null) && "runtime".equalsIgnoreCase(library.getScope()));
         // || library.getDependencyTrail().size() == 2;
     }
 
diff --git a/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileJSMojo.java b/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileJSMojo.java
index 03246c7..5f80ccb 100644
--- a/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileJSMojo.java
+++ b/royale-maven-plugin/src/main/java/org/apache/royale/maven/CompileJSMojo.java
@@ -76,12 +76,6 @@
     }
 
     @Override
-    protected boolean isForceSwcExternalLibraryPath() {
-        // The forceSwcExternalLibraryPath should only apply to Flash compilations.
-        return false;
-    }
-
-    @Override
     protected List<String> getCompilerArgs(File configFile) throws MojoExecutionException {
         List<String> args = super.getCompilerArgs(configFile);
         args.add("-compiler.targets=SWF,JSRoyale");
@@ -122,7 +116,7 @@
     @Override
     protected boolean includeLibrary(Artifact library) {
         String classifier = library.getClassifier();
-        return (classifier == null) && !("provided".equalsIgnoreCase(library.getScope()));
+        return (classifier == null) && !("runtime".equalsIgnoreCase(library.getScope()));
     }
 
     @Override
diff --git a/royaleunit-ant-tasks/build.xml b/royaleunit-ant-tasks/build.xml
new file mode 100644
index 0000000..d7a7105
--- /dev/null
+++ b/royaleunit-ant-tasks/build.xml
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project name="royaleunit-ant-tasks" default="main" basedir=".">
+
+  <!-- 
+
+      PROPERTIES
+
+  -->
+
+  <!-- The 'royaleunittasks' property is the absolute path, with forward slashes, -->
+  <!-- to the 'compiler' directory that contains this file. -->
+  <!-- All input paths are expressed as absolute paths starting with ${royaleunittasks}. -->
+  <pathconvert property="royaleunittasks" dirsep="/">
+      <path location="${basedir}"/>
+  </pathconvert>
+
+  <!-- The 'env' property contains all the environment variables -->
+  <property environment="env"/>
+  
+  <!-- Properties can be overridden locally by loading a local.properties file -->
+  <!-- Java 8 users probably need javadoc.params=-Xdoclint:none -->
+  <property file="${royaleunittasks}/local.properties"/>
+  <property file="${royaleunittasks}/../build.properties"/>
+  <property name="javadoc.params" value="" />
+  
+  <!-- The 'sdk' property is the absolute path, with forward slashes, to the compiler/lib directory -->
+  <!-- where a Royale SDK is built -->
+  <!-- All output paths are expressed as absolute paths starting with ${sdk} -->
+  <property name="sdk" value="${royaleunittasks}/../compiler-jx/lib"/>
+
+  <!-- Options for <javac> tasks -->
+  <property name="javac.debug" value="true"/>
+  <property name="javac.deprecation" value="false"/>
+  <property name="javac.src" value="1.6"/>
+
+  <!-- JAR manifest entries -->
+  <property name="manifest.sealed" value="false"/>
+  <property name="manifest.Implementation-Title" value="Apache Royale - RoyaleUnit Ant Tasks"/>
+  <property name="manifest.Implementation-Version" value="${release.version}"/>
+  <property name="manifest.Implementation-Vendor" value="Apache Software Foundation"/>
+
+  <property name="royaleunittasks.ant.binaries" value="**/*.class"/>
+  
+  <!-- env.BUILD_NUMBER is set by Jenkins CI -->
+  <condition property="build.number" value="nightly-${env.BUILD_NUMBER}">
+      <isset property="env.BUILD_NUMBER"/>
+  </condition>
+      
+  <!--
+
+      CLASSPATHS
+
+  -->
+
+  <path id="classpath">
+      <fileset dir="${sdk}" includes="**/*.jar"/>
+  </path>
+
+  <target name="download" description="Downloads third-party JARs">
+      <ant antfile="${royaleunittasks}/src/main/resources/downloads.xml" dir="${royaleunittasks}/src/main/resources" inheritAll="false"/>
+  </target>
+
+  <target name="compile" description="compile" depends="download">
+    <mkdir dir="${royaleunittasks}/target/classes"/>
+    <javac debug="${javac.debug}" deprecation="${javac.deprecation}"
+            includes="**/*.java" destdir="${royaleunittasks}/target/classes" classpathref="classpath" includeAntRuntime="true"
+            source="${javac.src}" target="${javac.src}">
+        <src path="${royaleunittasks}/src/main/java"/>
+        <compilerarg value="-Xlint:all,-path,-fallthrough,-cast"/>
+    </javac>
+    <copy todir="${royaleunittasks}/target/classes">
+        <fileset dir="${royaleunittasks}/src/main/resources" includes="**/*.properties"/>
+    </copy>
+  </target>
+  
+  <target name="set.royale.royaleunittasks.jar.uptodate">
+    <uptodate property="royale.royaleunittasks.jar.uptodate"
+              targetfile="${sdk}/royaleUnitTasks.jar">
+      <srcfiles dir="${royaleunittasks}/target/classes">
+        <include name="**/*.class"/>
+        <include name="**/*.properties"/>
+      </srcfiles>
+    </uptodate>
+  </target>
+  
+  <target name="royale.royaleunittasks.jar" depends="set.royale.royaleunittasks.jar.uptodate" unless="royale.royaleunittasks.jar.uptodate">
+    <mkdir dir="${royaleunittasks}/target/classes/META-INF"/>
+    <copy file="${basedir}/../LICENSE.base" tofile="${royaleunittasks}/target/classes/META-INF/LICENSE"/>
+    <copy file="${basedir}/../NOTICE.base" tofile="${royaleunittasks}/target/classes/META-INF/NOTICE"/>
+    <mkdir dir="${sdk}"/>
+    <jar file="${sdk}/royaleUnitTasks.jar" basedir="${royaleunittasks}/target/classes" >
+      <include name="META-INF/LICENSE"/>
+      <include name="META-INF/NOTICE"/>
+      <manifest>
+        <attribute name="Sealed" value="${manifest.sealed}"/>
+        <attribute name="Implementation-Title" value="${manifest.Implementation-Title}"/>
+        <attribute name="Implementation-Version" value="${manifest.Implementation-Version}.${build.number}"/>
+        <attribute name="Implementation-Vendor" value="${manifest.Implementation-Vendor}"/>
+        <attribute name="Class-Path" value="dom4j.jar java-websocket.jar slf4j-api.jar"/>
+      </manifest>
+      <fileset dir="${royaleunittasks}/src/main/resources" includes="royaleUnitTasks.tasks"/>
+      <fileset dir="${royaleunittasks}/src/main/resources" includes="TestRunner.template"/>
+      <fileset dir="${royaleunittasks}/src/main/resources" includes="royaleUnitDescriptor.template"/>
+      <fileset dir="${royaleunittasks}/target/classes" includes="${royaleunittasks.ant.binaries}"/>
+    </jar>
+  </target>
+
+  <target name="jar" depends="compile,royale.royaleunittasks.jar"
+        description="Creates JAR files"/>
+    
+  <!--
+
+      SDK
+
+  -->
+  
+  <target name="sdk" depends="jar, test" description="Builds the royaleUnitTasks.jar"/>
+
+  <target name="main" depends="sdk" description="Default target - Builds the royaleUnitTasks.jar">
+    <tstamp>
+      <format property="build.datetime" pattern="MM/dd/yyyy hh:mm:ss aa"/>
+    </tstamp>
+    <echo>RoyaleUnit Ant Tasks main completed on ${build.datetime}</echo>
+  </target>
+
+  <target name="test" depends="jar" description="Runs JUnit tests">
+      <!--<ant dir="src/test" />-->
+  </target>
+  
+  <!--
+
+      CLEANUP
+
+  -->
+
+  <target name="clean" description="clean">
+    <ant antfile="${basedir}/src/main/resources/downloads.xml" target="clean" dir="${basedir}" />
+      <delete dir="${royaleunittasks}/target" failonerror="false"/>
+      <delete file="${sdk}/royaleUnitTasks.jar" failonerror="false"/>
+  </target>
+
+  <target name="wipe" depends="clean" description="Wipes everything that didn't come from Git.">
+  </target>
+</project>
\ No newline at end of file
diff --git a/royaleunit-ant-tasks/pom.xml b/royaleunit-ant-tasks/pom.xml
new file mode 100644
index 0000000..f7f96ef
--- /dev/null
+++ b/royaleunit-ant-tasks/pom.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+

+  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.

+

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+  <modelVersion>4.0.0</modelVersion>

+

+  <parent>

+    <groupId>org.apache.royale.compiler</groupId>

+    <artifactId>royale-compiler-parent</artifactId>

+    <version>0.9.6</version>

+  </parent>

+

+  <artifactId>royaleunit-ant-tasks</artifactId>

+  <version>0.9.6</version>

+

+  <name>Apache Royale: RoyaleUnit Ant Tasks</name>

+

+  <dependencies>

+    <dependency>

+      <groupId>org.apache.ant</groupId>

+      <artifactId>ant</artifactId>

+      <version>1.7.0</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.ant</groupId>

+      <artifactId>ant-launcher</artifactId>

+      <version>1.7.0</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.ant</groupId>

+      <artifactId>ant-testutil</artifactId>

+      <version>1.7.0</version>

+    </dependency>

+    <dependency>

+      <groupId>dom4j</groupId>

+      <artifactId>dom4j</artifactId>

+      <version>1.6.1</version>

+    </dependency>

+    <dependency>

+      <groupId>org.java-websocket</groupId>

+      <artifactId>Java-WebSocket</artifactId>

+      <version>1.4.0</version>

+    </dependency>

+    <dependency>

+      <groupId>org.slf4j</groupId>

+      <artifactId>slf4j-simple</artifactId>

+      <version>1.7.25</version>

+    </dependency>

+  </dependencies>

+

+</project>

diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/IRoyaleUnitServer.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/IRoyaleUnitServer.java
new file mode 100644
index 0000000..e6f542b
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/IRoyaleUnitServer.java
@@ -0,0 +1,28 @@
+/*
+ * 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.royale.test.ant;
+
+import java.io.IOException;
+
+public interface IRoyaleUnitServer
+{
+    public void start() throws IOException;
+    public void stop() throws IOException, InterruptedException;
+    public boolean isPending();
+    public String readNextTokenFromSocket() throws IOException;
+    public Exception getException();
+}
\ No newline at end of file
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/LoggingUtil.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/LoggingUtil.java
new file mode 100644
index 0000000..0f1e8f4
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/LoggingUtil.java
@@ -0,0 +1,35 @@
+/*
+ * 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.royale.test.ant;
+
+public class LoggingUtil
+{
+    public static boolean VERBOSE = false;
+    
+    public static void log(String message)
+    {
+        log(message, false);
+    }
+    
+    public static void log(String message, boolean force)
+    {
+        if(VERBOSE || force)
+        {
+            System.out.println(message);
+        }
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/RoyaleUnitSocketServer.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/RoyaleUnitSocketServer.java
new file mode 100644
index 0000000..0152d9d
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/RoyaleUnitSocketServer.java
@@ -0,0 +1,282 @@
+/*
+ * 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.royale.test.ant;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.text.MessageFormat;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Class responsible for managing the connections to the test runner and any boiler plate in the network interactivity. 
+ */
+public class RoyaleUnitSocketServer implements IRoyaleUnitServer
+{
+    
+    private static final char NULL_BYTE = '\u0000';
+    private static final String POLICY_FILE_REQUEST = "<policy-file-request/>";
+    
+    //Uncomment to use DTD for validation rather than schema
+    //private static final String DOMAIN_POLICY = "<?xml version=\"1.0\"?><!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\"><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"{0}\" /></cross-domain-policy>";
+
+    private static final String DOMAIN_POLICY = 
+        "<?xml version=\"1.0\"?>"
+        + "<cross-domain-policy xmlns=\"http://localhost\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.adobe.com/xml/schemas PolicyFileSocket.xsd\">"
+        + "<allow-access-from domain=\"*\" to-ports=\"{0}\" />"
+        + "</cross-domain-policy>";
+    
+    private static final String START_OF_TEST_RUN_ACK = "<startOfTestRunAck/>";
+    private static final String END_OF_TEST_RUN_ACK = "<endOfTestRunAck/>";
+    
+    private int port;
+    private int timeout;
+    private int inboundBufferSize;  //if this is not set high enough, incoming data may clobber unread data in the buffer
+    private boolean waitForPolicyFile;
+
+    private ServerSocket serverSocket = null;
+    private Socket clientSocket = null;
+    private InputStreamReader inboundReader = null;
+    private OutputStreamWriter outboundWriter = null;
+
+    public RoyaleUnitSocketServer(int port, int timeout, int inboundBufferSize, boolean waitForPolicyFile)
+    {
+        this.port = port;
+        this.timeout = timeout;
+        this.inboundBufferSize = inboundBufferSize;
+        this.waitForPolicyFile = waitForPolicyFile;
+    }
+
+    /**
+     * Starts the socket server, managing policy file requests, and starting the test process.
+     */
+    public void start() throws IOException
+    {
+        LoggingUtil.log("Starting server ...");
+        
+        try
+        {
+            openServerSocket();
+            openClientSocket();
+            prepareClientSocket();
+        }
+        catch (SocketTimeoutException e)
+        {
+            throw new BuildException("Socket timeout waiting for royaleunit report", e);
+        }
+    }
+
+    public boolean isPending()
+    {
+        return false;
+    }
+
+    public Exception getException()
+    {
+        return null;
+    }
+    
+    /**
+     * Resets the client connection.
+     */
+    private void resetInboundStream() throws IOException
+    {
+        LoggingUtil.log("Resetting client connection ...");
+        
+        closeClientSocket();
+        openClientSocket();
+    }
+    
+    /**
+     * Creates a connection on the specified socket. Waits {socketTimeout}
+     * seconds for a client connection before throwing an error
+     */
+    private void openServerSocket() throws IOException
+    {
+        serverSocket = new ServerSocket(port);
+        serverSocket.setSoTimeout(timeout);
+
+        LoggingUtil.log("Opening server socket on port [" + port + "].");
+    }
+
+    /**
+     * Creates the client connection. This method will pause until the connection
+     * is made or the timout limit is reached.
+     * 
+     * Once a connection is established opens the in and out buffer.
+     */
+    private void openClientSocket() throws IOException
+    {
+        LoggingUtil.log("Waiting for client connection ...");
+        
+        // This method blocks until a connection is made.
+        clientSocket = serverSocket.accept();
+
+        LoggingUtil.log("Client connected.");
+        LoggingUtil.log("Setting inbound buffer size to [" + inboundBufferSize + "] bytes.");
+        
+        inboundReader = new InputStreamReader(new BufferedInputStream(clientSocket.getInputStream(), inboundBufferSize), "UTF-8");
+        outboundWriter = new OutputStreamWriter(new BufferedOutputStream(clientSocket.getOutputStream()), "UTF-8");
+        
+        LoggingUtil.log("Receiving data ...");
+    }
+    
+    /**
+     * Decides whether to send a policy request or a start ack
+     */
+    private void prepareClientSocket() throws IOException
+    {
+        // if it's a policy request, make sure the first thing we send is a policy response
+        if (waitForPolicyFile)
+        {
+            String request = readNextTokenFromSocket();
+            if (request.equals(POLICY_FILE_REQUEST))
+            {
+                LoggingUtil.log("Policy file requested.");
+                
+                sendPolicyFile();
+                resetInboundStream();
+            }
+        }
+
+        //tell client to start the testing process
+        sendTestRunStartAcknowledgement();
+    }
+    
+    /**
+     * Generate domain policy message and send 
+     */
+    private void sendPolicyFile() throws IOException
+    {
+        sendOutboundMessage(MessageFormat.format(DOMAIN_POLICY, new Object[] { Integer.toString(port) }));
+
+        LoggingUtil.log("Policy file sent.");
+    }
+
+    /**
+     * Generate and send message to inform test runner to begin sending test data
+     */
+    private void sendTestRunStartAcknowledgement() throws IOException
+    {
+        LoggingUtil.log("Sending acknowledgement to player to start sending test data ...\n");
+        
+        sendOutboundMessage(START_OF_TEST_RUN_ACK);
+    }
+    
+    /**
+     * Reads tokens from the socket input stream based on NULL_BYTE as a delimiter
+     */
+    public String readNextTokenFromSocket() throws IOException
+    {
+        StringBuffer buffer = new StringBuffer();
+        int piece = -1;
+
+        while ((piece = inboundReader.read()) != NULL_BYTE)
+        {
+            //Did we reach the end of the buffer?  Tell the user there is nothing more.
+            if (piece == -1)
+            {
+                return null;
+            }
+
+            final char chr = (char) piece;
+            buffer.append(chr);
+        }
+
+        //Did we recieve a message that the test run is over? Tell the user we have nothing more.
+        String token = buffer.toString();
+        
+        return token;
+    }
+    
+    private void sendOutboundMessage(String message) throws IOException
+    {
+        if(outboundWriter != null)
+        {
+            outboundWriter.write(message);
+            outboundWriter.write(NULL_BYTE);
+            outboundWriter.flush();
+        }
+    }
+
+    /**
+     * Stops the socket server, notifying the test runner, and closing the appropriate connections.
+     */
+    public void stop() throws IOException, InterruptedException
+    {
+        LoggingUtil.log("\nStopping server ...");
+        
+        sendTestRunEndAcknowledgement();
+        closeClientSocket();
+        closeServerSocket();
+    }
+    
+    /**
+     * Sends the end of test run to the listener to close the connection
+     */
+    private void sendTestRunEndAcknowledgement() throws IOException
+    {
+        LoggingUtil.log("End of test data reached, sending acknowledgement to player ...");
+        
+        sendOutboundMessage(END_OF_TEST_RUN_ACK);
+    }
+    
+    /**
+     * Closes the client connection and all buffers, ignoring any errors
+     */
+    private void closeClientSocket() throws IOException
+    {
+        LoggingUtil.log("Closing client connection ...");
+        
+        // Close the output stream.
+        if (outboundWriter != null)
+        {
+            outboundWriter.close();
+        }
+
+        // Close the input stream.
+        if (inboundReader != null)
+        {
+            inboundReader.close();
+        }
+
+        // Close the client socket.
+        if (clientSocket != null)
+        {
+            clientSocket.close();
+        }
+    }
+
+    /**
+     * Closes the server socket. Ignores any errors if unable to close
+     */
+    private void closeServerSocket() throws IOException
+    {
+        LoggingUtil.log("Closing server on port [" + port + "] ...");
+        
+        if (serverSocket != null)
+        {
+            serverSocket.close();
+        }
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/RoyaleUnitSocketThread.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/RoyaleUnitSocketThread.java
new file mode 100644
index 0000000..90e1211
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/RoyaleUnitSocketThread.java
@@ -0,0 +1,183 @@
+/*
+ * 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.royale.test.ant;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import org.apache.tools.ant.BuildException;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.apache.royale.test.ant.report.Report;
+import org.apache.royale.test.ant.report.Suite;
+
+/**
+ * Managing class for the RoyaleUnitSocketServer and report aggregation.
+ */
+public class RoyaleUnitSocketThread implements Callable<Object>
+{
+    // Messages from CIListener
+    private static final String END_OF_SUCCESS = "status=\"success\" />";
+    private static final String END_OF_FAILURE = "</testcase>";
+    private static final String END_OF_IGNORE = "<skipped /></testcase>";
+    private static final String END_OF_TEST_RUN = "<endOfTestRun/>";
+
+    // XML attribute labels
+    private static final String SUITE_ATTRIBUTE = "classname";
+
+    private File reportDir;
+
+    private IRoyaleUnitServer server;
+    private Map<String, Report> reports;
+
+    public RoyaleUnitSocketThread(IRoyaleUnitServer server, File reportDir, Map<String, Report> reports)
+    {
+        this.server = server;
+        this.reportDir = reportDir;
+        this.reports = reports;
+    }
+
+    /**
+     * When excuted, the thread will start the socket server and wait for inbound data and delegate reporting
+     */
+    //TODO: Clean up exception handling
+    public Object call() throws Exception
+    {
+        try
+        {
+            server.start();
+            parseInboundMessages();
+        }
+        catch (IOException e)
+        {
+            throw new BuildException("error receiving report from royaleunit", e);
+        }
+        finally
+        {
+            try
+            {
+                server.stop();
+            }
+            catch (IOException e)
+            {
+                throw new BuildException("could not close client/server socket");
+            }
+        }
+
+        //All done, let the process that spawned me know I've returned.
+        return null;
+    }
+
+    /**
+     * Used to iterate and interpret byte sent over the socket.
+     */
+    private void parseInboundMessages() throws IOException
+    {
+        while (true)
+        {
+            if (server.isPending())
+            {
+                //try again later
+                try
+                {
+                    Thread.sleep(100);
+                }
+                catch(Exception e) {}
+                continue;
+            }
+
+            if (server.getException() != null)
+            {
+                throw new BuildException(server.getException());
+            }
+
+            String request = server.readNextTokenFromSocket();
+            if (request == null)
+            {
+                break;
+            }
+            else if (request.equals(END_OF_TEST_RUN))
+            {
+                // The client has declared that the test run is complete
+                break;
+            }
+            else if (request.endsWith(END_OF_FAILURE) || request.endsWith(END_OF_SUCCESS) || request.endsWith(END_OF_IGNORE))
+            {
+                // Process all other known requests
+                processTestReport(request);
+            }
+            else
+            {
+                throw new BuildException("command [" + request + "] not understood");
+            }
+        }
+    }
+
+    /**
+     * Process the test report.
+     * 
+     * @param report
+     *           String that represents a complete test
+     */
+    private void processTestReport(String xml)
+    {
+        // Convert the string report into an XML document
+        Document test = parseReport(xml);
+
+        // Find the name of the suite
+        String suiteName = test.getRootElement().attributeValue(SUITE_ATTRIBUTE);
+
+        // Convert all instances of :: for file support
+        suiteName = suiteName.replaceAll("::", ".");
+
+        if (!reports.containsKey(suiteName))
+        {
+            reports.put(suiteName, new Report(new Suite(suiteName)));
+        }
+
+        // Fetch report, add test, and write to disk
+        Report report = reports.get(suiteName);
+        report.addTest(test);
+
+        report.save(reportDir);
+    }
+
+    /**
+     * Parse the parameter String and returns it as a document
+     * 
+     * @param report
+     *           String
+     * @return Document
+     */
+    private Document parseReport(String report)
+    {
+        try
+        {
+            final Document document = DocumentHelper.parseText(report);
+
+            return document;
+        }
+        catch (DocumentException e)
+        {
+            LoggingUtil.log(report);
+            throw new BuildException("Error parsing report.", e);
+        }
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/RoyaleUnitWebSocketServer.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/RoyaleUnitWebSocketServer.java
new file mode 100644
index 0000000..925e367
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/RoyaleUnitWebSocketServer.java
@@ -0,0 +1,161 @@
+/*
+ * 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.royale.test.ant;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.Callable;
+
+import org.apache.tools.ant.BuildException;
+import org.java_websocket.WebSocket;
+import org.java_websocket.handshake.ClientHandshake;
+import org.java_websocket.server.WebSocketServer;
+
+public class RoyaleUnitWebSocketServer extends WebSocketServer implements IRoyaleUnitServer
+{
+    private static final String START_OF_TEST_RUN_ACK = "<startOfTestRunAck/>";
+    private static final String END_OF_TEST_RUN_ACK = "<endOfTestRunAck/>";
+
+    public RoyaleUnitWebSocketServer(int port, int timeout)
+    {
+        super(new InetSocketAddress(port));
+        this.timeout = timeout;
+        //because we may be running many sets of tests in a short period of
+        //time, and the socket can end up in a timeout state after it is closed,
+        //this allows us to reuse the same port again quickly
+        this.setReuseAddr(true);
+    }
+
+    private int timeout;
+    private Timer timeoutTimer;
+    private List<String> queue = new ArrayList<String>();
+    private Exception resultException;
+
+    public Exception getException()
+    {
+        return resultException;
+    }
+
+    @Override
+    public void stop() throws IOException, InterruptedException
+    {
+        LoggingUtil.log("\nStopping server ...");
+
+        if(timeoutTimer != null)
+        {
+            timeoutTimer.cancel();
+            timeoutTimer = null;
+        }
+        
+        for(WebSocket socket : getConnections())
+        {
+            sendTestRunEndAcknowledgement(socket);
+        }
+        super.stop();
+    }
+
+    @Override
+    public void onOpen(WebSocket connection, ClientHandshake handshake)
+    {
+        if(timeoutTimer != null)
+        {
+            timeoutTimer.cancel();
+            timeoutTimer = null;
+        }
+
+        LoggingUtil.log("Client connected.");
+        LoggingUtil.log("Receiving data ...");
+        
+        sendTestRunStartAcknowledgement(connection);
+    }
+
+    @Override
+    public void onClose(WebSocket connection, int code, String reason, boolean remote)
+    {
+        Thread.currentThread().interrupt();
+    }
+
+    @Override
+    public void onMessage(WebSocket connection, String message)
+    {
+        queue.add(message);
+    }
+
+    @Override
+    public void onError(WebSocket connection, Exception ex)
+    {
+        resultException = ex;
+    }
+    
+    @Override
+    public void onStart()
+    {
+        LoggingUtil.log("Starting server ...");
+        LoggingUtil.log("Waiting for client connection ...");
+
+        timeoutTimer = new Timer();
+        timeoutTimer.schedule(new TimerTask()
+        {
+            public void run()
+            {
+                resultException = new BuildException("Socket timeout waiting for royaleunit report");
+            }
+        }, timeout);
+    }
+
+    public boolean isPending()
+    {
+       return resultException == null && queue.size() == 0;
+    }
+   
+    /**
+     * Reads tokens from the web socket
+     */
+    public String readNextTokenFromSocket() throws IOException
+    {
+        return queue.remove(0);
+    }
+   
+    private void sendOutboundMessage(WebSocket connection, String message)
+    {
+        connection.send(message);
+    }
+
+    /**
+     * Generate and send message to inform test runner to begin sending test data
+     */
+    private void sendTestRunStartAcknowledgement(WebSocket connection)
+    {
+       LoggingUtil.log("Sending acknowledgement to player to start sending test data ...\n");
+       
+       sendOutboundMessage(connection, START_OF_TEST_RUN_ACK);
+    }
+   
+    /**
+     * Sends the end of test run to the listener to close the connection
+     */
+    private void sendTestRunEndAcknowledgement(WebSocket connection)
+    {
+       LoggingUtil.log("End of test data reached, sending acknowledgement to player ...");
+       
+       sendOutboundMessage(connection, END_OF_TEST_RUN_ACK);
+    }
+}
\ No newline at end of file
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/OperatingSystem.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/OperatingSystem.java
new file mode 100644
index 0000000..7629055
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/OperatingSystem.java
@@ -0,0 +1,55 @@
+/*
+ * 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.royale.test.ant.launcher;
+
+import org.apache.royale.test.ant.LoggingUtil;
+
+public enum OperatingSystem
+{
+    WINDOWS, MACOSX, LINUX;
+
+    private static final String SUN_WINDOWS = "windows";
+    private static final String SUN_MACOSX = "mac os x";
+    private static final String OPENJDK_MACOSX = "darwin";
+    
+    /**
+     * Searches for Windows and Mac specificially and if not found defaults to Linux.
+     */
+    public static OperatingSystem identify()
+    {
+        OperatingSystem os = null;
+        String env = System.getProperty("os.name").toLowerCase();
+
+        if (env.startsWith(SUN_WINDOWS))
+        {
+            LoggingUtil.log("OS: [Windows]");
+            os = OperatingSystem.WINDOWS;
+        } 
+        else if (env.contains(SUN_MACOSX) || env.contains(OPENJDK_MACOSX))
+        {
+            LoggingUtil.log("OS: [Mac]");
+            os = OperatingSystem.MACOSX;
+        } 
+        else
+        {
+            LoggingUtil.log("OS: [Linux]");
+            os = OperatingSystem.LINUX;
+        }
+        
+        return os;
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/Command.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/Command.java
new file mode 100644
index 0000000..cc4f9ad
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/Command.java
@@ -0,0 +1,91 @@
+/*
+ * 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.royale.test.ant.launcher.commands;
+
+import java.io.IOException;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.royale.test.ant.LoggingUtil;
+
+public abstract class Command
+{
+    private Project project;
+    private Commandline commandLine;
+    private String[] environment;
+
+    public Command()
+    {
+        super();
+        this.commandLine = new Commandline();
+        environment = new String[0];
+    }
+
+    public void setProject(Project project)
+    {
+        this.project = project;
+    }
+
+    public Project getProject()
+    {
+        return project;
+    }
+
+    public Commandline getCommandLine()
+    {
+        return commandLine;
+    }
+    
+    public int execute() throws IOException
+    {
+        Execute execute = new Execute();
+        execute.setCommandline(getCommandLine().getCommandline());
+        execute.setAntRun(getProject());
+        execute.setEnvironment(getEnvironment());
+        
+        LoggingUtil.log(getCommandLine().describeCommand());
+        
+        return execute.execute();
+    }
+    
+    public Process launch() throws IOException
+    {
+        Execute execute = new Execute();
+        execute.setCommandline(getCommandLine().getCommandline());
+        execute.setAntRun(getProject());
+        execute.setEnvironment(getEnvironment());
+        
+        LoggingUtil.log(getCommandLine().describeCommand());
+        
+        execute.execute();
+        
+        //By default we use the Ant Execute task which does not give us a handle to a process
+        return null;
+    }
+
+    public void setEnvironment(String[] variables)
+    {
+        this.environment = variables;
+    }
+
+    public String[] getEnvironment()
+    {
+        return environment;
+    }
+
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/headless/XvncException.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/headless/XvncException.java
new file mode 100644
index 0000000..e7362f8
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/headless/XvncException.java
@@ -0,0 +1,36 @@
+/*
+ * 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.royale.test.ant.launcher.commands.headless;
+
+public class XvncException extends Exception
+{
+    private static final long serialVersionUID = -879079265370069307L;
+    
+    public XvncException()
+    {
+        super("Could not find the vncserver command.");
+    }
+
+    public XvncException(int baseDisplayNumber, int finalDisplayNumber)
+    {
+        super("Could not start xvnc using displays " 
+                + String.valueOf(baseDisplayNumber) 
+                + "-" 
+                + String.valueOf(finalDisplayNumber) 
+                + "; Consider adding to your launch script: killall Xvnc Xrealvnc; rm -fv /tmp/.X*-lock /tmp/.X11-unix/X*");
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/headless/XvncStartCommand.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/headless/XvncStartCommand.java
new file mode 100644
index 0000000..edbf01d
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/headless/XvncStartCommand.java
@@ -0,0 +1,64 @@
+/*
+ * 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.royale.test.ant.launcher.commands.headless;
+
+import java.io.IOException;
+
+import org.apache.royale.test.ant.LoggingUtil;
+import org.apache.royale.test.ant.launcher.commands.Command;
+
+public class XvncStartCommand extends Command
+{
+    private final String VNC_SERVER_COMMAND = "vncserver";
+    private final int MAX_DISPLAY_CYCLES = 2;
+    
+    private int baseDisplay;
+    private int currentDisplay;
+    
+    public XvncStartCommand(int display)
+    {
+        super();
+        this.baseDisplay = display;
+        this.currentDisplay = display;
+    }
+    
+    public void cycle() throws XvncException
+    {
+        if((currentDisplay - baseDisplay) == MAX_DISPLAY_CYCLES)
+        {
+            throw new XvncException(baseDisplay, currentDisplay);
+        }
+        
+        currentDisplay++;
+    }
+    
+    public int getCurrentDisplay()
+    {
+        return currentDisplay;
+    }
+    
+    @Override
+    public int execute() throws IOException
+    {
+        getCommandLine().setExecutable(VNC_SERVER_COMMAND);
+        getCommandLine().addArguments(new String[]{":" + String.valueOf(currentDisplay)});
+        
+        LoggingUtil.log("Attempting start on :" + currentDisplay + " ...");
+        
+        return super.execute();
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/headless/XvncStopCommand.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/headless/XvncStopCommand.java
new file mode 100644
index 0000000..c94605e
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/headless/XvncStopCommand.java
@@ -0,0 +1,45 @@
+/*
+ * 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.royale.test.ant.launcher.commands.headless;
+
+import java.io.IOException;
+
+import org.apache.royale.test.ant.LoggingUtil;
+import org.apache.royale.test.ant.launcher.commands.Command;
+
+public class XvncStopCommand extends Command
+{
+    private final String VNC_SERVER_COMMAND = "vncserver";
+    private int display;
+
+    public XvncStopCommand(int display)
+    {
+        super();
+        this.display = display;
+    }
+
+    @Override
+    public int execute() throws IOException
+    {
+        LoggingUtil.log("Terminating xvnc on :" + display);
+        
+        getCommandLine().setExecutable(VNC_SERVER_COMMAND);
+        getCommandLine().addArguments(new String[]{ "-kill", ":" + String.valueOf(display) });
+
+        return super.execute();
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/AdlCommand.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/AdlCommand.java
new file mode 100644
index 0000000..734327f
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/AdlCommand.java
@@ -0,0 +1,163 @@
+/*
+ * 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.royale.test.ant.launcher.commands.player;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.types.FilterSet;
+import org.apache.tools.ant.types.FilterSetCollection;
+import org.apache.tools.ant.types.Commandline.Argument;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.URLResource;
+import org.apache.tools.ant.util.ResourceUtils;
+import org.apache.royale.test.ant.LoggingUtil;
+
+public class AdlCommand extends DefaultPlayerCommand
+{
+    private final String ADT_JAR_PATH = "lib" + File.separatorChar + "adt.jar";
+    private final String DESCRIPTOR_TEMPLATE = "royaleUnitDescriptor.template";
+    private final String DESCRIPTOR_FILE = "royaleUnitDescriptor.xml";
+
+    private File precompiledAppDescriptor;
+
+    @Override
+    public File getFileToExecute()
+    {
+      if(getPrecompiledAppDescriptor() != null)
+      {
+          return new File(getPrecompiledAppDescriptor().getAbsolutePath());
+      }
+        return new File(getSwf().getParentFile().getAbsolutePath() + File.separatorChar + DESCRIPTOR_FILE);
+    }
+
+    /**
+     * Used to create the application descriptor used to invoke adl
+     */
+    private void createApplicationDescriptor()
+    {
+        try
+        {
+            //Template location in JAR
+            URLResource template = new URLResource(getClass().getResource("/" + DESCRIPTOR_TEMPLATE));
+
+            //Descriptor location, same location as SWF due to relative path required in descriptor
+            File descriptor = new File(getSwf().getParentFile().getAbsolutePath() + File.separatorChar + DESCRIPTOR_FILE);
+
+            //Create tokens to filter
+            Double versionNumber = getVersion();
+            FilterSet filters = new FilterSet();
+            filters.addFilter("ADL_SWF", getSwf().getName());
+            filters.addFilter("ADT_VERSION", Double.toString(versionNumber));
+            if(versionNumber > 2.0) {
+               filters.addFilter("VERSION_PROP", "versionNumber");
+            } else {
+               filters.addFilter("VERSION_PROP", "version");
+            }
+
+            //Copy descriptor template to SWF folder performing token replacement
+            ResourceUtils.copyResource(
+                template,
+                new FileResource(descriptor),
+                new FilterSetCollection(filters),
+                null,
+                true,
+                false,
+                null,
+                null,
+                getProject()
+            );
+
+            LoggingUtil.log("Created application descriptor at [" + descriptor.getAbsolutePath() + "]");
+        }
+        catch (Exception e)
+        {
+            throw new BuildException("Could not create application descriptor");
+        }
+    }
+
+    private double getVersion()
+    {
+        String outputProperty = "AIR_VERSION";
+
+        //Execute mxmlc to find SDK version number
+        Java task = new Java();
+        task.setFork(true);
+        task.setFailonerror(true);
+        task.setJar(new File(getProject().getProperty("ROYALE_HOME") + File.separatorChar + ADT_JAR_PATH));
+        task.setProject(getProject());
+        task.setDir(getProject().getBaseDir());
+        task.setOutputproperty(outputProperty);
+
+        Argument versionArgument = task.createArg();
+        versionArgument.setValue("-version");
+
+        task.execute();
+        double version = parseAdtVersionNumber( getProject().getProperty(outputProperty) );
+        LoggingUtil.log("Found AIR version: " + version);
+        return version;
+    }
+
+
+    private double parseAdtVersionNumber( String versionString )
+    {
+      double version;
+
+        //AIR 2.6 and greater only returns the version number.
+        if( versionString.startsWith("adt") )
+        {
+             //Parse version number and return as int
+            int prefixIndex = versionString.indexOf("adt version \"");
+            version = Double.parseDouble(versionString.substring(prefixIndex + 13, prefixIndex + 16));
+
+        }else
+        {
+           version = Double.parseDouble(versionString.substring(0, 3) );
+        }
+
+      return version;
+    }
+
+    @Override
+    public void prepare()
+    {
+        getCommandLine().setExecutable(generateExecutable());
+        getCommandLine().addArguments(new String[]{getFileToExecute().getAbsolutePath()});
+
+        if(getPrecompiledAppDescriptor() == null)
+        {
+           //Create Adl descriptor file
+           createApplicationDescriptor();
+        }
+    }
+
+    private String generateExecutable()
+    {
+        return getProject().getProperty("ROYALE_HOME") + "/bin/" + getDefaults().getAdlCommand();
+    }
+
+    public File getPrecompiledAppDescriptor()
+    {
+        return precompiledAppDescriptor;
+    }
+
+    public void setPrecompiledAppDescriptor(File precompiledAppDescriptor)
+    {
+        this.precompiledAppDescriptor = precompiledAppDescriptor;
+    }
+}
\ No newline at end of file
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/CustomPlayerCommand.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/CustomPlayerCommand.java
new file mode 100644
index 0000000..830af6e
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/CustomPlayerCommand.java
@@ -0,0 +1,124 @@
+/*
+ * 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.royale.test.ant.launcher.commands.player;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Vector;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.royale.test.ant.LoggingUtil;
+
+public class CustomPlayerCommand implements PlayerCommand
+{
+    private DefaultPlayerCommand proxiedCommand;
+    private File executable;
+
+    public PlayerCommand getProxiedCommand()
+    {
+        return proxiedCommand;
+    }
+    
+    public void setProxiedCommand(DefaultPlayerCommand playerCommand)
+    {
+        this.proxiedCommand = playerCommand;
+    }
+
+    public File getExecutable()
+    {
+        return executable;
+    }
+    
+    public void setExecutable(File executable)
+    {
+        this.executable = executable;
+    }
+    
+    public void setProject(Project project)
+    {
+        proxiedCommand.setProject(project);
+    }
+    
+    public void setSwf(File swf)
+    {
+        proxiedCommand.setSwf(swf);
+    }
+    
+    public String getUrl() {
+        return proxiedCommand.getUrl();
+    }
+
+    public void setUrl(String url) {
+        proxiedCommand.setUrl(url);
+    }
+    
+    public File getFileToExecute()
+    {
+        return proxiedCommand.getFileToExecute();
+    }
+    
+    public void prepare()
+    {
+        proxiedCommand.prepare();
+        
+        proxiedCommand.getCommandLine().setExecutable(executable.getAbsolutePath());
+        proxiedCommand.getCommandLine().clearArgs();
+        
+        if(getUrl() != null)
+        {    	  
+           proxiedCommand.getCommandLine().addArguments(new String[]{getUrl()});
+        } 
+        else 
+        {  
+           proxiedCommand.getCommandLine().addArguments(new String[]{getFileToExecute().getAbsolutePath()});
+        }
+
+    }
+    
+    public Process launch() throws IOException
+    {
+        LoggingUtil.log(proxiedCommand.getCommandLine().describeCommand());
+        
+        //execute the command directly
+        return Runtime.getRuntime().exec(
+                proxiedCommand.getCommandLine().getCommandline(), 
+                getJointEnvironment(), 
+                proxiedCommand.getProject().getBaseDir());
+    }
+
+    public void setEnvironment(String[] variables)
+    {
+        proxiedCommand.setEnvironment(variables);
+    }
+
+    /**
+     * Combine process environment variables and command's environment to emulate the default
+     * behavior of the Execute task.  Needed especially when user expects environment to be 
+     * available to custom command (e.g. - xvnc with player not on path).
+     */
+    @SuppressWarnings("unchecked")
+    private String[] getJointEnvironment()
+    {
+        Vector procEnvironment = Execute.getProcEnvironment();
+        String[] environment = new String[procEnvironment.size() + proxiedCommand.getEnvironment().length];
+        System.arraycopy(procEnvironment.toArray(), 0, environment, 0, procEnvironment.size());
+        System.arraycopy(proxiedCommand.getEnvironment(), 0, environment, procEnvironment.size(), proxiedCommand.getEnvironment().length);
+        
+        return environment;
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/DefaultPlayerCommand.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/DefaultPlayerCommand.java
new file mode 100644
index 0000000..92d0a83
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/DefaultPlayerCommand.java
@@ -0,0 +1,73 @@
+/*
+ * 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.royale.test.ant.launcher.commands.player;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.royale.test.ant.launcher.commands.Command;
+import org.apache.royale.test.ant.launcher.platforms.PlatformDefaults;
+
+public abstract class DefaultPlayerCommand extends Command implements PlayerCommand
+{
+    private String url;
+    private File swf;
+    private PlatformDefaults defaults;
+    
+    public DefaultPlayerCommand()
+    {
+        super();
+    }
+
+    public void setSwf(File swf)
+    {
+        this.swf = swf;
+    }
+
+    public File getSwf()
+    {
+        return swf;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }   
+
+    public void setDefaults(PlatformDefaults defaults)
+    {
+        this.defaults = defaults;
+    }
+
+    public PlatformDefaults getDefaults()
+    {
+        return defaults;
+    }
+    
+    public abstract File getFileToExecute();
+    
+    public abstract void prepare();
+    
+    @Override
+    public Process launch() throws IOException
+    {
+        return super.launch();
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/FlashPlayerCommand.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/FlashPlayerCommand.java
new file mode 100644
index 0000000..725becf
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/FlashPlayerCommand.java
@@ -0,0 +1,88 @@
+/*
+ * 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.royale.test.ant.launcher.commands.player;
+
+import java.io.File;
+
+
+/**
+ * Abstracts the assembly of a command-line call to the Flash player for all platforms.  
+ */
+public class FlashPlayerCommand extends DefaultPlayerCommand
+{
+    public static final String TRUST_FILENAME = "royaleUnit.cfg";
+    
+    private boolean localTrusted;
+    
+    public FlashPlayerCommand()
+    {
+        super();
+    }
+
+    @Override
+    public File getFileToExecute()
+    {
+        return getSwf();
+    }
+    
+    public void setLocalTrusted(boolean localTrusted)
+    {
+        this.localTrusted = localTrusted;
+    }
+
+    public boolean isLocalTrusted()
+    {
+        return localTrusted;
+    }
+
+    @Override
+    public void prepare()
+    {
+         //Determine if we have a URL value.
+         //This should be populated by setting the 'swf' property equal to a remote http hosted SWF.
+         if(getUrl() != null && getUrl() != "")
+         {
+            //setup the command line now for remote URL
+            getCommandLine().setExecutable(getDefaults().getOpenCommand());
+            getCommandLine().addArguments(getDefaults().getOpenSystemArguments());
+            getCommandLine().addArguments(new String[]{getUrl()});
+            
+            //There is no need to add to the local trust because we're going to be loading the swf from a remote location.
+            
+         } 
+         //Determine if we have a local SWF to run.
+         //This should be populated by setting the 'swf' property equal to a swf on your local file system. 
+         else if(getSwf() != null) {
+              
+            //setup the command line now with local SWF file location
+            getCommandLine().setExecutable(getDefaults().getOpenCommand());
+            getCommandLine().addArguments(getDefaults().getOpenSystemArguments());
+            getCommandLine().addArguments(new String[]{getFileToExecute().getAbsolutePath()});
+
+            //handle local trust for locally stored swf file
+            TrustFile trustFile = new TrustFile(getProject(), getDefaults().getFlashPlayerUserTrustDirectory(), getDefaults().getFlashPlayerGlobalTrustDirectory());
+            if (localTrusted)
+            {
+                trustFile.add(getSwf());
+            }
+            else
+            {
+                trustFile.remove(getSwf());
+            }		   
+         }
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/PlayerCommand.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/PlayerCommand.java
new file mode 100644
index 0000000..157c198
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/PlayerCommand.java
@@ -0,0 +1,38 @@
+/*
+ * 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.royale.test.ant.launcher.commands.player;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+
+/**
+ * Class used to abstract an extension of {@link Execute} that has its own handle to a {@link Project}
+ * and can setup context for using the project
+ */
+public interface PlayerCommand
+{
+    public void setProject(Project project);
+    public void setEnvironment(String[] variables);
+    public File getFileToExecute();
+    public void setSwf(File swf);
+    public void setUrl(String url);
+    public void prepare();
+    public Process launch() throws IOException;
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/PlayerCommandFactory.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/PlayerCommandFactory.java
new file mode 100644
index 0000000..6961262
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/PlayerCommandFactory.java
@@ -0,0 +1,85 @@
+/*
+ * 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.royale.test.ant.launcher.commands.player;
+
+import java.io.File;
+
+import org.apache.royale.test.ant.launcher.OperatingSystem;
+import org.apache.royale.test.ant.launcher.platforms.LinuxDefaults;
+import org.apache.royale.test.ant.launcher.platforms.MacOSXDefaults;
+import org.apache.royale.test.ant.launcher.platforms.WindowsDefaults;
+
+public class PlayerCommandFactory
+{
+    /**
+     * Factory method to create the appropriate player and provide it with a set of defaults for
+     * the executing platform.
+     * 
+     * @param os
+     * @param player  "flash" or "air"
+     * @param customCommand
+     * @param localTrusted
+     * @return Desired player command with platform defaults possibly wrapped in a custom command
+     */
+    public static PlayerCommand createPlayer(OperatingSystem os, String player, File customCommand, boolean localTrusted)
+    {
+        PlayerCommand newInstance = null;
+
+        DefaultPlayerCommand defaultInstance = null;
+        
+        //choose player
+        if (player.equals("flash") || player.equals("html"))
+        {
+            FlashPlayerCommand fpCommand = new FlashPlayerCommand();
+            fpCommand.setLocalTrusted(localTrusted);
+            defaultInstance = fpCommand;
+        }
+        else
+        {
+            defaultInstance = new AdlCommand();
+        }
+        
+        //set defaults
+        if (os.equals(OperatingSystem.WINDOWS))
+        {
+            defaultInstance.setDefaults(new WindowsDefaults());
+        }
+        else if(os.equals(OperatingSystem.MACOSX))
+        {
+            defaultInstance.setDefaults(new MacOSXDefaults());
+        }
+        else
+        {
+            defaultInstance.setDefaults(new LinuxDefaults());
+        }
+        
+        //if a custom command has been provide, use it to wrap the default command
+        if(customCommand != null)
+        {
+            CustomPlayerCommand customInstance = new CustomPlayerCommand();
+            customInstance.setProxiedCommand(defaultInstance);
+            customInstance.setExecutable(customCommand);
+            newInstance = customInstance;
+        }
+        else
+        {
+            newInstance = defaultInstance;
+        }
+        
+        return newInstance;
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/TrustFile.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/TrustFile.java
new file mode 100644
index 0000000..0e1653a
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/commands/player/TrustFile.java
@@ -0,0 +1,170 @@
+/*
+ * 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.royale.test.ant.launcher.commands.player;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.royale.test.ant.LoggingUtil;
+
+public class TrustFile
+{
+    public static final String TRUST_FILENAME = "royaleUnit.cfg";
+
+    private File trustDirectory;
+    private File trustFile;
+    private List<String> paths;
+
+    public TrustFile(Project project, File userTrustDirectory, File globaTrustDirectory)
+    {
+        // determine which trust directory to use
+        this.trustDirectory = userTrustDirectory != null ? userTrustDirectory : globaTrustDirectory;
+
+        // create it if it doesn't exist
+        if (!this.trustDirectory.exists())
+        {
+            try
+            {
+                trustDirectory.mkdirs();
+            }
+            catch (Exception e)
+            {
+                throw new BuildException("Could not create Flash Player trust directory at [" + trustDirectory.getAbsolutePath() + "]; permission denied.");
+            }
+        }
+
+        // locate trust file
+        this.trustFile = project.resolveFile(trustDirectory.getAbsolutePath() + "/" + TRUST_FILENAME);
+
+        // parse trust file contents
+        this.paths = read();
+    }
+
+    private List<String> read()
+    {
+        List<String> paths = new ArrayList<String>();
+
+        if (trustFile.exists())
+        {
+            try
+            {
+                BufferedReader reader = new BufferedReader(new FileReader(trustFile));
+                String path = null;
+
+                while ((path = reader.readLine()) != null)
+                {
+                    paths.add(path);
+                }
+
+                reader.close();
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+        }
+
+        return paths;
+    }
+
+    public void add(String url) 
+    {
+        String path = new File(url).getParentFile().getAbsolutePath();
+        addPath(path);
+    }
+    
+    public void add(File swf)
+    {
+        String path = swf.getParentFile().getAbsolutePath();
+        addPath(path);
+    }
+    
+    private void addPath(String path)
+    {
+        // create the appropriate FP trust directory is it doesn't exist
+        if (!trustDirectory.exists())
+        {
+            trustDirectory.mkdir();
+        }
+
+        // Add path if it doesn't exist
+        if (!paths.contains(path))
+        {
+            paths.add(path);
+
+            // Write file
+            write();
+
+            LoggingUtil.log("Updated local trust file at [" + trustFile.getAbsolutePath() + "], added [" + path + "].");
+        }
+        else
+        {
+            LoggingUtil.log("Entry [" + path + "] already available in local trust file at [" + trustFile.getAbsolutePath() + "].");
+        }	   
+    }
+
+    private void write()
+    {
+        try
+        {
+            FileWriter writer = new FileWriter(trustFile, false);
+
+            for (String path : paths)
+            {
+                writer.write(path + System.getProperty("line.separator"));
+            }
+
+            writer.close();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    public void remove(String url) {
+        String path = new File(url).getParentFile().getAbsolutePath();
+        removePath(path); 
+    }
+    
+    public void remove(File swf)
+    {
+        // remove path if exists
+        String path = swf.getParentFile().getAbsolutePath();
+        removePath(path);
+    }
+    
+    public void removePath(String path) 
+    {
+        if (paths.contains(path))
+        {
+            paths.remove(path);
+
+            // write out new copy of file
+            write();
+
+            LoggingUtil.log("Updated local trust file at [" + trustFile.getAbsolutePath() + "], removed [" + path + "].");
+        }	   
+    }
+    
+}
\ No newline at end of file
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/contexts/DefaultContext.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/contexts/DefaultContext.java
new file mode 100644
index 0000000..412eb35
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/contexts/DefaultContext.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.royale.test.ant.launcher.contexts;
+
+import java.io.IOException;
+
+import org.apache.tools.ant.Project;
+import org.apache.royale.test.ant.launcher.commands.player.PlayerCommand;
+
+public class DefaultContext implements ExecutionContext
+{
+    private PlayerCommand command;
+    
+    @SuppressWarnings("unused")
+    private Project project;
+    
+    public void setProject(Project project)
+    {
+        this.project = project;
+    }
+    public void setCommand(PlayerCommand command)
+    {
+        this.command = command;
+    }
+
+    public void start() throws IOException
+    {
+        //prep anything the command needs to run
+        command.prepare();
+    }
+
+    public void stop(Process playerProcess) throws IOException
+    {
+        //destroy the process related to the player if it exists
+        if(playerProcess != null)
+        {
+            playerProcess.destroy();
+        }
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/contexts/ExecutionContext.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/contexts/ExecutionContext.java
new file mode 100644
index 0000000..1b5c97d
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/contexts/ExecutionContext.java
@@ -0,0 +1,47 @@
+/*
+ * 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.royale.test.ant.launcher.contexts;
+
+import java.io.IOException;
+
+import org.apache.tools.ant.Project;
+import org.apache.royale.test.ant.launcher.commands.player.PlayerCommand;
+
+/**
+ * Basis for executing a player command.
+ */
+public interface ExecutionContext
+{
+    public void setProject(Project project);
+    public void setCommand(PlayerCommand command);
+    
+    /**
+     * Starts the execution context and any work associated with the individual implementations.
+     * 
+     * @throws IOException
+     */
+    public void start() throws IOException;
+    
+    /**
+     * Stops the execution context and manages the player Process as well as any work associated
+     * with the individual implementations.
+     * 
+     * @param playerProcess
+     * @throws IOException
+     */
+    public void stop(Process playerProcess) throws IOException;
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/contexts/ExecutionContextFactory.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/contexts/ExecutionContextFactory.java
new file mode 100644
index 0000000..89be35d
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/contexts/ExecutionContextFactory.java
@@ -0,0 +1,49 @@
+/*
+ * 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.royale.test.ant.launcher.contexts;
+
+import org.apache.royale.test.ant.launcher.OperatingSystem;
+
+public class ExecutionContextFactory
+{
+    /**
+     * Used to generate new instances of an execution context based on the OS and whether the build should run
+     * headlessly.
+     * 
+     * @param os Current OS.
+     * @param headless Should the build run headlessly.
+     * @param display The vnc display number to use if headless
+     * 
+     * @return
+     */
+    public static ExecutionContext createContext(OperatingSystem os, boolean headless, int display)
+    {
+        boolean trulyHeadless = headless && (os == OperatingSystem.LINUX);
+        ExecutionContext context = null;
+        
+        if(trulyHeadless)
+        {
+            context = new HeadlessContext(display); 
+        }
+        else
+        {
+            context = new DefaultContext();
+        }
+        
+        return context;
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/contexts/HeadlessContext.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/contexts/HeadlessContext.java
new file mode 100644
index 0000000..d18abe3
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/contexts/HeadlessContext.java
@@ -0,0 +1,99 @@
+/*
+ * 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.royale.test.ant.launcher.contexts;
+
+import java.io.IOException;
+
+import org.apache.tools.ant.Project;
+import org.apache.royale.test.ant.LoggingUtil;
+import org.apache.royale.test.ant.launcher.commands.headless.XvncException;
+import org.apache.royale.test.ant.launcher.commands.headless.XvncStartCommand;
+import org.apache.royale.test.ant.launcher.commands.headless.XvncStopCommand;
+import org.apache.royale.test.ant.launcher.commands.player.PlayerCommand;
+
+/**
+ * Context used to wrap a call to the player command in a start and stop of a vncserver.
+ * All vncserver commands are blocking.
+ */
+public class HeadlessContext implements ExecutionContext
+{
+    private PlayerCommand playerCommand;
+    private int startDisplay;
+    private int finalDisplay;
+    private Project project;
+    
+    public HeadlessContext(int display)
+    {
+        this.startDisplay = display;
+    }
+    
+    public void setProject(Project project)
+    {
+        this.project = project;
+    }
+    
+    public void setCommand(PlayerCommand command)
+    {
+        this.playerCommand = command;
+    }
+    
+    public void start() throws IOException
+    {
+        // setup vncserver on the provided display
+        XvncStartCommand xvncStart = new XvncStartCommand(startDisplay);
+        xvncStart.setProject(project);
+        
+        LoggingUtil.log("Starting xvnc", true);
+        
+        // execute the maximum number of cycle times before throwing an exception
+        while (xvncStart.execute() != 0)
+        {
+            LoggingUtil.log("Cannot start xnvc on :" + xvncStart.getCurrentDisplay() + ", cycling ...");
+            
+            try
+            {
+                xvncStart.cycle();
+            }
+            catch (XvncException xe) {
+                throw new IOException(xe);
+            }
+        }
+            
+        finalDisplay = xvncStart.getCurrentDisplay();
+        
+        //setup player command to use the right display in its env when launching
+        playerCommand.setEnvironment(new String[]{ "DISPLAY=:" + finalDisplay });
+        LoggingUtil.log("Setting DISPLAY=:" + finalDisplay);
+        
+        //prep anything the command needs to run
+        playerCommand.prepare();
+    }
+    
+    public void stop(Process playerProcess) throws IOException
+    {
+        // destroy the process related to the player if it exists
+        if(playerProcess != null)
+        {
+            playerProcess.destroy();
+        }
+        
+        // Now stop the vncserver that the player has been destroyed
+        XvncStopCommand xvncStop = new XvncStopCommand(finalDisplay);
+        xvncStop.setProject(project);
+        xvncStop.execute();
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/platforms/LinuxDefaults.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/platforms/LinuxDefaults.java
new file mode 100644
index 0000000..8d78688
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/platforms/LinuxDefaults.java
@@ -0,0 +1,57 @@
+/*
+ * 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.royale.test.ant.launcher.platforms;
+
+import java.io.File;
+
+public class LinuxDefaults implements PlatformDefaults
+{
+
+    public String getAdlCommand()
+    {
+        return "adl";
+    }
+
+    public File getFlashPlayerGlobalTrustDirectory()
+    {
+        return new File("/etc/adobe/FlashPlayerTrust/");
+    }
+
+    public File getFlashPlayerUserTrustDirectory()
+    {
+        File file = null;
+        
+        String home = System.getenv("HOME");
+        if(home != null && !home.equals(""))
+        {
+            file = new File(home + "/.macromedia/Flash_Player/#Security/FlashPlayerTrust/");
+        }
+        
+        return file;
+    }
+
+    public String getOpenCommand()
+    {
+        return "gflashplayer";
+    }
+
+    public String[] getOpenSystemArguments()
+    {
+        return new String[]{};
+    }
+
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/platforms/MacOSXDefaults.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/platforms/MacOSXDefaults.java
new file mode 100644
index 0000000..385cb28
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/platforms/MacOSXDefaults.java
@@ -0,0 +1,57 @@
+/*
+ * 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.royale.test.ant.launcher.platforms;
+
+import java.io.File;
+
+public class MacOSXDefaults implements PlatformDefaults
+{
+
+    public String getAdlCommand()
+    {
+        return "adl";
+    }
+
+    public File getFlashPlayerGlobalTrustDirectory()
+    {
+        return new File("/Library/Application Support/Macromedia/FlashPlayerTrust/");
+    }
+
+    public File getFlashPlayerUserTrustDirectory()
+    {
+        File file = null;
+        
+        String home = System.getenv("HOME");
+        if(home != null && !home.equals(""))
+        {
+            file = new File(home + "/Library/Preferences/Macromedia/Flash Player/#Security/FlashPlayerTrust/");
+        }
+        
+        return file;
+    }
+
+    public String getOpenCommand()
+    {
+        return "open";
+    }
+
+    public String[] getOpenSystemArguments()
+    {
+        return new String[]{};
+    }
+
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/platforms/PlatformDefaults.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/platforms/PlatformDefaults.java
new file mode 100644
index 0000000..49f2e44
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/platforms/PlatformDefaults.java
@@ -0,0 +1,29 @@
+/*
+ * 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.royale.test.ant.launcher.platforms;
+
+import java.io.File;
+
+public interface PlatformDefaults
+{
+    public File getFlashPlayerUserTrustDirectory();
+    public File getFlashPlayerGlobalTrustDirectory();
+    public String getOpenCommand();
+    public String[] getOpenSystemArguments();
+    public String getAdlCommand();
+    //public String getFlashPlayerCommand();
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/platforms/WindowsDefaults.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/platforms/WindowsDefaults.java
new file mode 100644
index 0000000..fd7def0
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/launcher/platforms/WindowsDefaults.java
@@ -0,0 +1,57 @@
+/*
+ * 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.royale.test.ant.launcher.platforms;
+
+import java.io.File;
+
+public class WindowsDefaults implements PlatformDefaults
+{
+
+    public String getAdlCommand()
+    {
+        return "adl.exe";
+    }
+
+    public File getFlashPlayerGlobalTrustDirectory()
+    {
+        return new File(System.getenv("SYSTEMROOT") + "\\system32\\Macromed\\Flash\\FlashPlayerTrust\\");
+    }
+
+    public File getFlashPlayerUserTrustDirectory()
+    {
+        File file = null;
+        
+        String appData = System.getenv("APPDATA");
+        if(appData != null && !appData.equals(""))
+        {
+            file = new File(appData + "\\Macromedia\\Flash Player\\#Security\\FlashPlayerTrust\\");
+        }
+        
+        return file;
+    }
+
+    public String getOpenCommand()
+    {
+        return "rundll32";
+    }
+
+    public String[] getOpenSystemArguments()
+    {
+        return new String[]{"url.dll,FileProtocolHandler"};
+    }
+
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/report/Report.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/report/Report.java
new file mode 100644
index 0000000..a608072
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/report/Report.java
@@ -0,0 +1,252 @@
+/*
+ * 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.royale.test.ant.report;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.DateUtils;
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.XMLWriter;
+import org.apache.royale.test.ant.LoggingUtil;
+
+public class Report
+{
+    private static final String FAILURE = "failure";
+    private static final String ERROR = "error";
+    private static final String IGNORE = "ignore";
+
+    private static final String TEST_SUITE = "testsuite";
+    private static final String NAME_ATTRIBUTE_LABEL = "name";
+    private static final String FAILURE_ATTRIBUTE_LABEL = "failures";
+    private static final String ERROR_ATTRIBUTE_LABEL = "errors";
+    private static final String IGNORE_ATTRIBUTE_LABEL = "skipped";
+    private static final String TIME_ATTRIBUTE_LABEL = "time";
+    private static final String TESTS_ATTRIBUTE_LABEL = "tests";
+    private static final String HOSTNAME_ATTRIBUTE_LABEL = "hostname";
+    private static final String TIMESTAMP_ATTRIBUTE_LABEL = "timestamp";
+
+    private static final String FILENAME_PREFIX = "TEST-";
+    private static final String FILENAME_EXTENSION = ".xml";
+
+    // Exception messages
+    private static final String FAILED_TEST = "RoyaleUnit test {0} in suite {1} failed.";
+    private static final String ERRORED_TEST = "RoyaleUnit test {0} in suite {1} had errors.";
+    private static final String IGNORED_TEST = "RoyaleUnit test {0} in suite {1} was ignored.";
+    private static final String TEST_INFO = "Suite: {0}\nTests run: {1}, Failures: {2}, Errors: {3}, Skipped: {4}, Time elapsed: {5} sec";
+    private static final String ERROR_SAVING_REPORT = "Error saving report.";
+
+    // XML attribute labels
+    private static final String CLASSNAME_ATTRIBUTE = "classname";
+    private static final String NAME_ATTRIBUTE = "name";
+    private static final String STATUS_ATTRIBUTE = "status";
+    private static final String TIME_ATTRIBUTE = "time";
+
+    protected Suite suite;
+    private Document document;
+    private List<String> recordedRuns;
+
+    public Report(Suite suite)
+    {
+        this.recordedRuns = new ArrayList<String>();
+        this.suite = suite;
+
+        // Create a new XML document
+        document = DocumentHelper.createDocument();
+
+        // Add the test suite attributes to the document
+        document
+                .addElement(TEST_SUITE)
+                .addAttribute(NAME_ATTRIBUTE_LABEL, suite.getName())
+                .addAttribute(TESTS_ATTRIBUTE_LABEL,
+                        String.valueOf(suite.getTests()))
+                .addAttribute(FAILURE_ATTRIBUTE_LABEL,
+                        String.valueOf(suite.getFailures()))
+                .addAttribute(ERROR_ATTRIBUTE_LABEL,
+                        String.valueOf(suite.getErrors()))
+                .addAttribute(IGNORE_ATTRIBUTE_LABEL,
+                        String.valueOf(suite.getSkips()))
+                .addAttribute(TIME_ATTRIBUTE_LABEL, String.valueOf(suite.getTime()));
+    }
+
+    /**
+     * Adds the test to the suite report given an XML test document
+     */
+    public void addTest(Document test)
+    {
+        Element root = test.getRootElement();
+        
+        // Add to the number of tests in this suite if not seen and not null
+        String testMethod = root.attributeValue(NAME_ATTRIBUTE);
+        if(!recordedRuns.contains(testMethod) && !testMethod.equals("null"))
+        {
+            recordedRuns.add(testMethod);
+            suite.addTest();
+        }
+        
+        //add test time to total time
+        long time = Long.parseLong(root.attributeValue(TIME_ATTRIBUTE));
+        suite.addTime(time);
+        root.attribute(TIME_ATTRIBUTE).setText(formatTime(time));
+
+        //If the test method name is null, then make it the classname
+        if(root.attributeValue(NAME_ATTRIBUTE).equals("null"))
+        {
+            root.attribute(NAME_ATTRIBUTE).setText(root.attributeValue(CLASSNAME_ATTRIBUTE));
+        }
+        
+        // Add the test to the report document
+        document.getRootElement().add(root);
+
+        // Check for special status adjustments to make to suite
+        checkForStatus(test);
+        
+        //remove status attribute since it's only used by the report
+        root.remove(root.attribute(STATUS_ATTRIBUTE));
+    }
+    
+    private String formatTime(long time)
+    {
+        return String.format("%.3f", new Double(time / 1000.0000));
+    }
+
+    /**
+     * Updates counts for failed, error, and ignore on suite as well as logs what
+     * failed if told to use logging.
+     * 
+     * @param test
+     *           Test XML document
+     */
+    private void checkForStatus(Document test)
+    {
+        // Get the root element and pull the test name and status
+        final Element root = test.getRootElement();
+        final String name = root.attributeValue(NAME_ATTRIBUTE);
+        final String status = root.attributeValue(STATUS_ATTRIBUTE);
+
+        String format = null;
+        if (status.equals(FAILURE))
+        {
+            format = FAILED_TEST;
+            suite.addFailure();
+        } 
+        else if (status.equals(ERROR))
+        {
+            format = ERRORED_TEST;
+            suite.addError();
+        } 
+        else if (status.equals(IGNORE))
+        {
+            format = IGNORED_TEST;
+            suite.addSkip();
+        }
+
+        // Creates the fail message for use with verbose
+        if (format != null)
+        {
+            final String message = MessageFormat.format(format, new Object[]
+            { name, suite });
+            LoggingUtil.log(message);
+        }
+    }
+
+    /**
+     * Determines if any failures (errors or failures) have occurred in this
+     * report.
+     */
+    public boolean hasFailures()
+    {
+        return (suite.getErrors() > 0 || suite.getFailures() > 0);
+    }
+
+    /**
+     * Write the report XML document out to file
+     * 
+     * @param reportDir
+     *           Directory to hold report file.
+     */
+    public void save(File reportDir) throws BuildException
+    {
+        try
+        {
+            // Open the file matching the parameter suite
+            final File file = new File(reportDir, FILENAME_PREFIX + suite + FILENAME_EXTENSION);
+
+            // Retrieve the root element and adjust the failures and test attributes
+            Element root = document.getRootElement();
+            root.addAttribute(FAILURE_ATTRIBUTE_LABEL, String.valueOf(suite.getFailures()));
+            root.addAttribute(ERROR_ATTRIBUTE_LABEL, String.valueOf(suite.getErrors()));
+            root.addAttribute(TESTS_ATTRIBUTE_LABEL, String.valueOf(suite.getTests()));
+            root.addAttribute(IGNORE_ATTRIBUTE_LABEL, String.valueOf(suite.getSkips()));
+            root.addAttribute(TIME_ATTRIBUTE_LABEL, String.valueOf(formatTime(suite.getTime())));
+            root.addAttribute(HOSTNAME_ATTRIBUTE_LABEL, getHostname());
+            
+            final String timestamp = DateUtils.format(new Date(), DateUtils.ISO8601_DATETIME_PATTERN);
+            root.addAttribute(TIMESTAMP_ATTRIBUTE_LABEL, timestamp);
+
+            // Write the updated suite
+            final OutputFormat format = OutputFormat.createPrettyPrint();
+            final XMLWriter writer = new XMLWriter(new FileOutputStream(file), format);
+            writer.write(document);
+            writer.close();
+        }
+        catch (Exception e)
+        {
+            throw new BuildException(ERROR_SAVING_REPORT, e);
+        }
+    }
+
+    private String getHostname()
+    {
+        try
+        {
+            return InetAddress.getLocalHost().getHostName();
+        } catch (UnknownHostException e)
+        {
+            return "localhost";
+        }
+    }
+
+    public String getSummary()
+    {
+        String summary = "";
+
+        try
+        {
+            summary = MessageFormat.format(TEST_INFO, new Object[]
+            { new String(suite.getName()), new Integer(suite.getTests()),
+                    new Integer(suite.getFailures()),
+                    new Integer(suite.getErrors()), new Integer(suite.getSkips()),
+                    formatTime(suite.getTime()) });
+        } catch (Exception e)
+        {
+            // ignore
+        }
+
+        return summary;
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/report/Reports.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/report/Reports.java
new file mode 100644
index 0000000..3184097
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/report/Reports.java
@@ -0,0 +1,100 @@
+/*
+ * 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.royale.test.ant.report;
+
+import java.text.MessageFormat;
+import java.util.HashMap;
+
+/**
+ * Aggregate class representing a collection of Reports stored in a Map<String, Report>
+ */
+public class Reports extends HashMap<String, Report>
+{
+    private static final long serialVersionUID = 2078272511659655555L;
+    private static final String TEST_INFO = "Tests run: {0}, Failures: {1}, Errors: {2}, Skipped: {3}, Time elapsed: {4} sec";
+
+    public Reports()
+    {
+        super();
+    }
+    
+    /**
+     * String version of all reports.
+     */
+    public String getSummary()
+    {
+        String summary = "";
+        int runs = 0;
+        int errors = 0;
+        int failures = 0;
+        int skips = 0;
+        long time = 0;
+        
+        for(Report report : this.values())
+        {
+            runs += report.suite.getTests();
+            errors += report.suite.getErrors();
+            failures += report.suite.getFailures();
+            skips += report.suite.getSkips();
+            time += report.suite.getTime();
+            
+            summary += report.getSummary() + "\n";
+        }
+        
+        summary += "\nResults :\n\n";
+        
+        try
+        {
+            summary += MessageFormat.format(TEST_INFO, new Object[] { 
+                    new Integer(runs), 
+                    new Integer(failures), 
+                    new Integer(errors),
+                    new Integer(skips),
+                    formatTime(time)
+                });
+        }
+        catch(Exception e)
+        {
+            summary += "Error occurred while generating summary ...";
+        }
+        
+        summary += "\n";
+        
+        return summary;
+    }
+    
+    private String formatTime(long time)
+    {
+        return String.format("%.3f", new Double(time / 1000.0000));
+    }
+    
+    /**
+     * Determines if any reports have failures
+     */
+    public boolean hasFailures()
+    {
+        for(Report report : this.values())
+        {
+            if(report.hasFailures())
+            {
+                return true;
+            }
+        }
+        
+        return false;
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/report/Suite.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/report/Suite.java
new file mode 100644
index 0000000..fe9bd28
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/report/Suite.java
@@ -0,0 +1,94 @@
+/*
+ * 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.royale.test.ant.report;
+
+public class Suite
+{
+    private String _name;
+    private int _tests = 0;
+    private int _failures = 0;
+    private int _errors = 0;
+    private int _skips = 0;
+    private long _time = 0;
+
+    public Suite(String name)
+    {
+        super();
+        _name = name;
+    }
+
+    public void addTest()
+    {
+        _tests++;
+    }
+
+    public void addFailure()
+    {
+        _failures++;
+    }
+
+    public void addError()
+    {
+        _errors++;
+    }
+    
+    public void addSkip()
+    {
+        _skips++;
+    }
+
+    public String getName()
+    {
+        return _name;
+    }
+
+    public int getTests()
+    {
+        return _tests;
+    }
+
+    public int getFailures()
+    {
+        return _failures;
+    }
+
+    public int getErrors()
+    {
+        return _errors;
+    }
+    
+    public int getSkips()
+    {
+        return _skips;
+    }
+
+    public long getTime()
+    {
+        return _time;
+    }
+    
+    public void addTime(long time)
+    {
+        _time += time;
+    }
+
+    @Override
+    public String toString()
+    {
+        return _name;
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/Compilation.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/Compilation.java
new file mode 100644
index 0000000..e20cf71
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/Compilation.java
@@ -0,0 +1,219 @@
+/*
+ * 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.royale.test.ant.tasks;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.types.FilterSet;
+import org.apache.tools.ant.types.FilterSetCollection;
+import org.apache.tools.ant.types.Commandline.Argument;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.URLResource;
+import org.apache.tools.ant.util.ResourceUtils;
+import org.apache.royale.test.ant.LoggingUtil;
+import org.apache.royale.test.ant.tasks.configuration.CompilationConfiguration;
+
+public class Compilation
+{
+    private final String BASIC_APPLICATION_CLASS = "Application";
+    private final String MXML2006_PREFIX = "mx";
+    private final String MXML2006_NAMESPACE="xmlns:" + MXML2006_PREFIX + "=\"http://www.adobe.com/2006/mxml\"";
+    private final String MXML2009_PREFIX = "fx";
+    private final String MXML2009_NAMESPACE="xmlns:" + MXML2009_PREFIX + "=\"http://ns.adobe.com/mxml/2009\"";
+    private final String BASIC_PREFIX = "js";
+    private final String BASIC_NAMESPACE = "xmlns:" + BASIC_PREFIX + "=\"library://ns.apache.org/royale/basic\"";
+    private final String CI_LISTENER = "CIListener";
+    private final String AIR_CI_LISTENER = "AirCIListener";
+    private final String TESTRUNNER_TEMPLATE = "TestRunner.template";
+    private final String TESTRUNNER_FILE = "TestRunner.mxml";
+    private final String MXMLC_RELATIVE_PATH = "lib/mxmlc.jar";
+    private final String FRAMEWORKS_RELATIVE_PATH = "frameworks";
+    private final String SWF_FILENAME = "TestRunner.swf";
+    
+    private CompilationConfiguration configuration;
+    private Project project;
+    private String mxmlcPath;
+    
+    public Compilation(Project project, CompilationConfiguration configuration)
+    {
+        this.project = project;
+        this.configuration = configuration;
+        mxmlcPath = configuration.getRoyaleHome().getAbsolutePath() + File.separatorChar + MXMLC_RELATIVE_PATH;
+    }
+    
+    public File compile() throws BuildException
+    {
+        configuration.log();
+
+        File runnerFile = generateTestRunnerFromTemplate(configuration.getWorkingDir());
+        File finalFile = new File(configuration.getWorkingDir().getAbsolutePath() + File.separatorChar + SWF_FILENAME);
+        
+        Java compilationTask = createJavaTask(runnerFile, finalFile);
+        LoggingUtil.log("Compiling test classes: [" + configuration.getTestSources().getCanonicalClasses(", ") + "]", true);
+        LoggingUtil.log(compilationTask.getCommandLine().describeCommand());
+        
+        if(compilationTask.executeJava() != 0)
+        {
+            throw new BuildException("Compilation failed:\n" + project.getProperty("MXMLC_ERROR"));
+        }
+        
+        return finalFile;
+    }
+    
+    private File generateTestRunnerFromTemplate(File workingDir) throws BuildException
+    {
+        try
+        {
+            int sdkVersion = getSDKVersion();
+            
+            String namespaces = MXML2009_NAMESPACE + "\n" + BASIC_NAMESPACE;
+            String ciListener = configuration.getPlayer().equals("flash") ? CI_LISTENER : AIR_CI_LISTENER;
+            
+            File runner = new File(workingDir.getAbsolutePath() + File.separatorChar + TESTRUNNER_FILE);
+            
+            //Template location in JAR
+            URLResource template = new URLResource(getClass().getResource("/" + TESTRUNNER_TEMPLATE));
+            
+            //Create tokens to filter
+            FilterSet filters = new FilterSet();
+            filters.addFilter("APPLICATION_PREFIX", BASIC_PREFIX);
+            filters.addFilter("APPLICATION_CLASS", BASIC_APPLICATION_CLASS);
+            filters.addFilter("NAMESPACES", namespaces);
+            filters.addFilter("MXML_PREFIX", MXML2009_PREFIX);
+            filters.addFilter("CI_LISTENER_CLASS", ciListener);
+            filters.addFilter("CLASS_REFS", configuration.getTestSources().getClasses());
+            filters.addFilter("IMPORT_REFS", configuration.getTestSources().getImports());
+            
+            //Copy descriptor template to SWF folder performing token replacement
+            ResourceUtils.copyResource(
+                template,
+                new FileResource(runner),
+                new FilterSetCollection(filters),
+                null,
+                true,
+                false,
+                null,
+                null,
+                project
+            );
+            
+            LoggingUtil.log("Created test runner at [" + runner.getAbsolutePath() + "]");
+            
+            return runner;
+        }
+        catch (Exception e)
+        {
+            throw new BuildException("Could not create test runner from template.", e);
+        }
+    }
+    
+    private int getSDKVersion()
+    {
+        String outputProperty = "SDK_VERSION";
+        
+        //Execute mxmlc to find SDK version number
+        Java task = new Java();
+        task.setFork(true);
+        task.setFailonerror(true);
+        task.setJar(new File(mxmlcPath));
+        task.setProject(project);
+        task.setDir(project.getBaseDir());
+        task.setOutputproperty(outputProperty);
+        
+        Argument versionArgument = task.createArg();
+        versionArgument.setValue("--version");
+        
+        task.execute();
+        
+        //Parse version number and return as int
+        String output = project.getProperty(outputProperty);
+        int prefixIndex = output.indexOf("Version ");
+        int version = Integer.parseInt(output.substring(prefixIndex + 8, prefixIndex + 9));
+        
+        LoggingUtil.log("Found SDK version: " + version);
+        
+        return version;
+    }
+    
+    private Java createJavaTask(File runnerFile, File finalFile)
+    {
+        String frameworksPath = configuration.getRoyaleHome().getAbsolutePath() + File.separatorChar + FRAMEWORKS_RELATIVE_PATH;
+        
+        Java task = new Java();
+        task.setFork(true);
+        task.setFailonerror(true);
+        task.setJar(new File(mxmlcPath));
+        task.setProject(project);
+        task.setDir(project.getBaseDir());
+        task.setMaxmemory("256M"); //MXMLC needs to eat
+        task.setErrorProperty("MXMLC_ERROR");
+        
+        Argument royaleLibArgument = task.createArg();
+        royaleLibArgument.setLine("+royalelib \"" + frameworksPath + "\"");
+        
+        if(configuration.getPlayer().equals("air"))
+        {
+            Argument airConfigArgument = task.createArg();
+            airConfigArgument.setValue("+configname=air");
+        }
+        
+        Argument outputFile = task.createArg();
+        outputFile.setLine("-output \"" + finalFile.getAbsolutePath() + "\"");
+        
+        Argument sourcePath = task.createArg();
+        sourcePath.setLine("-source-path " + configuration.getSources().getPathElements(" ") + " " + configuration.getTestSources().getPathElements(" "));
+        
+        determineLibraryPath( task );
+      
+        determineLoadConfigArgument( task );
+         
+        Argument debug = task.createArg();
+        debug.setLine( "-debug=" + configuration.getDebug() );
+
+        Argument headlessServer = task.createArg();
+        headlessServer.setLine("-headless-server=true");
+        
+        
+        Argument mainFile = task.createArg();
+        mainFile.setValue(runnerFile.getAbsolutePath());
+        
+        return task;
+    }
+    
+    
+    private void determineLoadConfigArgument(Java java)
+    {
+        if(configuration.getLoadConfig() != null)
+        {
+            Argument argument = java.createArg();
+            argument.setLine(configuration.getLoadConfig().getCommandLineArgument());
+        }
+    }
+
+    private void determineLibraryPath(Java java)
+    {
+        if(!configuration.getLibraries().getPathElements(" -library-path+=").isEmpty())
+        {
+            Argument libraryPath = java.createArg();
+            libraryPath.setLine("-library-path+=" + configuration.getLibraries().getPathElements(" -library-path+="));
+        }
+    }
+    
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/RoyaleUnitTask.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/RoyaleUnitTask.java
new file mode 100644
index 0000000..d01e03a
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/RoyaleUnitTask.java
@@ -0,0 +1,214 @@
+/*
+ * 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.royale.test.ant.tasks;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DynamicElement;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.royale.test.ant.tasks.configuration.TaskConfiguration;
+import org.apache.royale.test.ant.tasks.types.LoadConfig;
+
+public class RoyaleUnitTask extends Task implements DynamicElement
+{
+    private TaskConfiguration configuration;
+
+    public RoyaleUnitTask()
+    {
+    }
+    
+    @Override
+    public void setProject(Project project)
+    {
+        super.setProject(project);
+        configuration = new TaskConfiguration(project);
+    }
+    
+    /**
+     * Sets local trusted, default is false
+     * 
+     * @param localTrusted
+     */
+    public void setLocalTrusted(final boolean localTrusted)
+    {
+        configuration.setLocalTrusted(localTrusted);
+    }
+
+    /**
+     * Set the port to receive the test results on. Default is 1024
+     * 
+     * @param serverPort
+     *           the port to set.
+     */
+    public void setPort(final int serverPort)
+    {
+        configuration.setPort(serverPort);
+    }
+
+    /**
+     * Set the timeout for receiving the royaleunit report.
+     * 
+     * @param timeout
+     *           in milliseconds.
+     */
+    public void setTimeout(final int timeout)
+    {
+        configuration.setSocketTimeout(timeout);
+    }
+
+    /**
+     * The buffer size the {@RoyaleUnitSocketServer} uses
+     * for its inbound data stream.
+     */
+    public void setBuffer(final int size)
+    {
+        configuration.setServerBufferSize(size);
+    }
+
+    /**
+     * The SWF for the RoyaleUnit tests to run.
+     * 
+     * @param testSWF
+     *           the SWF to set.
+     */
+    public void setSWF(final String testSWF)
+    {
+        configuration.setSwf(testSWF);
+    }
+
+    /**
+     * Set the directory to output the test reports to.
+     * 
+     * @param toDir
+     *           the directory to set.
+     */
+    public void setToDir(final String toDir)
+    {
+        configuration.setReportDir(toDir);
+    }
+
+    /**
+     * Should we fail the build if the royale tests fail?
+     * 
+     * @param fail
+     */
+    public void setHaltonfailure(final boolean fail)
+    {
+        configuration.setFailOnTestFailure(fail);
+    }
+
+    /**
+     * Custom ant property noting test failure
+     * 
+     * @param failprop
+     */
+    public void setFailureproperty(final String failprop)
+    {
+        configuration.setFailureProperty(failprop);
+    }
+
+    /**
+     * Toggle display of descriptive messages
+     * 
+     * @param verbose
+     */
+    public void setVerbose(final boolean verbose)
+    {
+        configuration.setVerbose(verbose);
+    }
+
+    public void setPlayer(String player)
+    {
+        configuration.setPlayer(player);
+    }
+
+    public void setCommand(String executableFilePath)
+    {
+        configuration.setCommand(executableFilePath);
+    }
+
+    public void setHeadless(boolean headless)
+    {
+        configuration.setHeadless(headless);
+    }
+
+    public void setDisplay(int number)
+    {
+        configuration.setDisplay(number);
+    }
+    
+    public void addSource(FileSet fileset)
+    {
+        configuration.addSource(fileset);
+    }
+    
+    public void addTestSource(FileSet fileset)
+    {
+        configuration.addTestSource(fileset);
+    }
+    
+    public void addLibrary(FileSet fileset)
+    {
+        configuration.addLibrary(fileset);
+    }
+    
+    public void setWorkingDir(String workingDirPath)
+    {
+        configuration.setWorkingDir(workingDirPath);
+    }
+    
+    /**
+     * Called by Ant to execute the task.
+     */
+    public void execute() throws BuildException
+    {
+        //verify entire configuration
+        configuration.verify();
+        
+        //compile tests if necessary
+        if(configuration.shouldCompile())
+        {
+            Compilation compilation = new Compilation(getProject(), configuration.getCompilationConfiguration());
+            configuration.setSwf(compilation.compile());
+        }
+        
+        //executes tests
+        TestRun testRun = new TestRun(getProject(), configuration.getTestRunConfiguration());
+        testRun.run();
+    }
+    
+    public void setDebug(boolean value)
+    {
+         configuration.setDebug(value);
+    }
+
+    public Object createDynamicElement(String arg0) throws BuildException 
+    {
+        if("load-config".equals(arg0))
+        {
+            LoadConfig loadconfig = new LoadConfig();
+            configuration.setLoadConfig(loadconfig);
+            return loadconfig;
+        } 
+        else
+        {
+            throw new BuildException( "The <royaleUnit> type doesn't support the " + arg0 + "nested element");
+        }
+    }
+
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/TestRun.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/TestRun.java
new file mode 100644
index 0000000..531474b
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/TestRun.java
@@ -0,0 +1,196 @@
+/*
+ * 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.royale.test.ant.tasks;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.royale.test.ant.RoyaleUnitSocketServer;
+import org.apache.royale.test.ant.RoyaleUnitSocketThread;
+import org.apache.royale.test.ant.RoyaleUnitWebSocketServer;
+import org.apache.royale.test.ant.IRoyaleUnitServer;
+import org.apache.royale.test.ant.LoggingUtil;
+import org.apache.royale.test.ant.launcher.commands.player.AdlCommand;
+import org.apache.royale.test.ant.launcher.commands.player.PlayerCommand;
+import org.apache.royale.test.ant.launcher.commands.player.PlayerCommandFactory;
+import org.apache.royale.test.ant.launcher.contexts.ExecutionContext;
+import org.apache.royale.test.ant.launcher.contexts.ExecutionContextFactory;
+import org.apache.royale.test.ant.report.Reports;
+import org.apache.royale.test.ant.tasks.configuration.TestRunConfiguration;
+
+public class TestRun
+{
+    private final String TRUE = "true";
+    
+    private TestRunConfiguration configuration;
+    private Project project;
+    
+    private Reports reports;
+
+    public TestRun(Project project, TestRunConfiguration configuration)
+    {
+        this.project = project;
+        this.configuration = configuration;
+        this.reports = new Reports();
+    }
+    
+    public void run() throws BuildException
+    {
+        configuration.log();
+
+        try
+        {
+            // setup daemon
+            Future<Object> daemon = setupSocketThread();
+
+            // run the execution context and player
+            PlayerCommand player = obtainPlayer();
+            ExecutionContext context = obtainContext(player);
+            
+            //start the execution context
+            context.start();
+        
+            //launch the player
+            Process process = player.launch();
+
+            try
+            {
+                // block until daemon is completely done with all test data
+                daemon.get();
+            }
+            finally
+            {
+                //stop the execution context now that socket thread is done
+                context.stop(process);
+            }
+
+            // print summaries and check for failure
+            analyzeReports();
+
+        } 
+        catch (Exception e)
+        {
+            throw new BuildException(e);
+        }
+    }
+    
+    /**
+     * Fetch the player command to execute the SWF.
+     * 
+     * @return PlayerCommand based on user config
+     */
+    protected PlayerCommand obtainPlayer()
+    {
+        // get command from factory
+        PlayerCommand command = PlayerCommandFactory.createPlayer(
+                configuration.getOs(), 
+                configuration.getPlayer(), 
+                configuration.getCommand(), 
+                configuration.isLocalTrusted());
+        
+        command.setProject(project);
+        command.setSwf(configuration.getSwf());
+        command.setUrl(configuration.getUrl());
+        
+        if(command instanceof AdlCommand) 
+        {
+           ((AdlCommand)command).setPrecompiledAppDescriptor(configuration.getPrecompiledAppDescriptor());
+        }
+        
+        return command;
+    }
+    
+    /**
+     * 
+     * @param player PlayerCommand which should be executed
+     * @return Context to wrap the execution of the PlayerCommand
+     */
+    protected ExecutionContext obtainContext(PlayerCommand player)
+    {
+        ExecutionContext context = ExecutionContextFactory.createContext(
+                configuration.getOs(), 
+                configuration.isHeadless(), 
+                configuration.getDisplay());
+        
+        context.setProject(project);
+        context.setCommand(player);
+        
+        return context;
+    }
+    
+    /**
+     * Create a server socket for receiving the test reports from RoyaleUnit. We
+     * read and write the test reports inside of a Thread.
+     */
+    protected Future<Object> setupSocketThread()
+    {
+        LoggingUtil.log("Setting up server process ...");
+
+        // Create server for use by thread
+        IRoyaleUnitServer server = null;
+        if(configuration.getPlayer().equals("html"))
+        {
+            server = new RoyaleUnitWebSocketServer(
+                configuration.getPort(), configuration.getSocketTimeout());
+        }
+        else
+        {
+            server = new RoyaleUnitSocketServer(configuration.getPort(), 
+                    configuration.getSocketTimeout(), configuration.getServerBufferSize(), 
+                    configuration.usePolicyFile());
+        }
+
+        // Get handle to specialized object to run in separate thread.
+        Callable<Object> operation = new RoyaleUnitSocketThread(server,
+                configuration.getReportDir(), reports);
+
+        // Get handle to service to run object in thread.
+        ExecutorService executor = Executors.newSingleThreadExecutor();
+
+        // Run object in thread and return Future.
+        return executor.submit(operation);
+    }
+
+    /**
+     * End of test report run. Called at the end of a test run. If verbose is set
+     * to true reads all suites in the suite list and prints out a descriptive
+     * message including the name of the suite, number of tests run and number of
+     * tests failed, ignores any errors. If any tests failed during the test run,
+     * the build is halted.
+     */
+    protected void analyzeReports()
+    {
+        LoggingUtil.log("Analyzing reports ...");
+
+        // print out all report summaries
+        LoggingUtil.log("\n" + reports.getSummary(), true);
+
+        if (reports.hasFailures())
+        {
+            project.setNewProperty(configuration.getFailureProperty(), TRUE);
+
+            if (configuration.isFailOnTestFailure())
+            {
+                throw new BuildException("RoyaleUnit tests failed during the test run.");
+            }
+        }
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/configuration/CompilationConfiguration.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/configuration/CompilationConfiguration.java
new file mode 100644
index 0000000..9013625
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/configuration/CompilationConfiguration.java
@@ -0,0 +1,160 @@
+/*
+ * 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.royale.test.ant.tasks.configuration;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.royale.test.ant.LoggingUtil;
+import org.apache.royale.test.ant.tasks.types.LibraryPaths;
+import org.apache.royale.test.ant.tasks.types.LoadConfig;
+import org.apache.royale.test.ant.tasks.types.SourcePaths;
+
+public class CompilationConfiguration implements StepConfiguration
+{
+    private SourcePaths sources;
+    private SourcePaths testSources;
+    private LibraryPaths libraries;
+    private File royaleHome;
+    private String player;
+    private File workingDir;
+
+    public CompilationConfiguration()
+    {
+        sources = new SourcePaths();
+        testSources = new SourcePaths();
+        libraries = new LibraryPaths();
+        debug = false;
+    }
+    
+    public File getRoyaleHome()
+    {
+        return royaleHome;
+    }
+    
+    public void setRoyaleHome(File royaleHome)
+    {
+        this.royaleHome = royaleHome;
+    }
+
+    public void addLibrary(FileSet fileset)
+    {
+        this.libraries.add(fileset);
+    }
+    
+    public LibraryPaths getLibraries()
+    {
+        return libraries;
+    }
+    
+    public String getPlayer()
+    {
+        return player;
+    }
+    
+    public void setPlayer(String player)
+    {
+        this.player = player;
+    }
+    
+    public void addSource(FileSet fileset)
+    {
+        this.sources.add(fileset);
+    }
+    
+    public SourcePaths getSources()
+    {
+        return sources;
+    }
+    
+    public void addTestSource(FileSet fileset)
+    {
+        this.testSources.add(fileset);
+    }
+    
+    public SourcePaths getTestSources()
+    {
+        return testSources;
+    }
+    
+    public void setWorkingDir(File workingDir)
+    {
+        this.workingDir = workingDir;
+    }
+
+    public File getWorkingDir()
+    {
+        return workingDir;
+    }
+
+    public void validate() throws BuildException
+    {
+        if(!testSources.exists())
+        {
+            throw new BuildException("One of the directories specified as a 'testSource' element does not exist.");
+        }
+        
+        if(testSources.exists() && testSources.isEmpty())
+        {
+            throw new BuildException("No test files could be found for the provided 'testSource' elements.");
+        }
+        
+        if(!libraries.exists())
+        {
+            throw new BuildException("One of the directories specified as a 'library' element does not exist.");
+        }
+        
+        if(libraries.exists() && libraries.isEmpty() && loadConfig == null)
+        {
+            throw new BuildException("'library' elements not specified or 'load-config' element not specified. Also possible no SWC files could be found for the provided 'library' elements.");
+        }
+    }
+    
+    public void log()
+    {
+        LoggingUtil.log("Using the following settings for compilation:");
+        LoggingUtil.log("\tROYALE_HOME: [" + royaleHome.getAbsolutePath() + "]");
+        LoggingUtil.log("\tplayer: [" + player + "]");
+        LoggingUtil.log("\tsourceDirectories: [" + sources.getPathElements(",") + "]");
+        LoggingUtil.log("\ttestSourceDirectories: [" + testSources.getPathElements(",") + "]");
+        LoggingUtil.log("\tlibraries: [" + libraries.getPathElements(",") + "]");
+    }
+    
+    private boolean debug;
+    public boolean getDebug()
+    {
+        return debug;
+    }
+
+    public void setDebug(boolean value)
+    {
+        debug = value;
+    }
+    
+    private LoadConfig loadConfig;
+    public void setLoadConfig(LoadConfig loadconfig)
+    {
+        loadConfig = loadconfig;
+    }
+
+    public LoadConfig getLoadConfig()
+    {
+        return loadConfig;
+    }
+    
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/configuration/StepConfiguration.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/configuration/StepConfiguration.java
new file mode 100644
index 0000000..ea58a9c
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/configuration/StepConfiguration.java
@@ -0,0 +1,25 @@
+/*
+ * 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.royale.test.ant.tasks.configuration;
+
+import org.apache.tools.ant.BuildException;
+
+public interface StepConfiguration
+{
+    public void validate() throws BuildException;
+    public void log();
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/configuration/TaskConfiguration.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/configuration/TaskConfiguration.java
new file mode 100644
index 0000000..4bf24d0
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/configuration/TaskConfiguration.java
@@ -0,0 +1,310 @@
+/*
+ * 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.royale.test.ant.tasks.configuration;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.royale.test.ant.LoggingUtil;
+import org.apache.royale.test.ant.tasks.types.LoadConfig;
+
+public class TaskConfiguration
+{
+    private final String DEFAULT_WORKING_PATH = ".";
+    private final String DEFAULT_REPORT_PATH = ".";
+    private final List<String> VALID_PLAYERS = Arrays.asList(new String[]{"flash", "air", "html"});
+    
+    private String player = "flash";
+    private File reportDir = null;
+    private File workingDir = null;
+    private boolean verbose = false;
+    private File royaleHome = null;
+    
+    private Project project;
+    private CompilationConfiguration compilationConfiguration;
+    private TestRunConfiguration testRunConfiguration;
+    
+    public TaskConfiguration(Project project)
+    {
+        this.project = project;
+        this.compilationConfiguration = new CompilationConfiguration();
+        this.testRunConfiguration = new TestRunConfiguration();
+        
+        if(project.getProperty("ROYALE_HOME") != null)
+        {
+            this.royaleHome = new File(project.getProperty("ROYALE_HOME"));
+        }
+    }
+    
+    //Used to verify that a string is also a properly formatted URL
+    //When determining if the passed 'swf' property value is remote or local this is crucial.
+    protected boolean isValidURL(String urlStr ) {
+         try {
+             URL url = new URL( urlStr );
+             LoggingUtil.log("my protocol " + url.getProtocol().toString() );
+             if( url.getProtocol().toUpperCase().equals("HTTP") || url.getProtocol().toUpperCase().equals("HTTPS") ) {
+                 LoggingUtil.log("Valid URL returning TRUE" );
+                 return true;	    		
+             } else {
+                 //no protocol so this isn't a URL at all, it might a local path or an invalid address
+                 LoggingUtil.log("Valid URL returning FALSE" );
+                 return false;
+             }
+             
+         }
+         catch( MalformedURLException e ) {
+             return false;
+         }
+    }
+    
+    public CompilationConfiguration getCompilationConfiguration()
+    {
+        return compilationConfiguration;
+    }
+    
+    public TestRunConfiguration getTestRunConfiguration()
+    {
+        return testRunConfiguration;
+    }
+
+    public void setCommand(String commandPath)
+    {
+        testRunConfiguration.setCommand(project.resolveFile(commandPath));
+    }
+    
+    public void setDisplay(int display)
+    {
+        testRunConfiguration.setDisplay(display);
+    }
+
+    public void setFailOnTestFailure(boolean failOnTestFailure)
+    {
+        testRunConfiguration.setFailOnTestFailure(failOnTestFailure);
+    }
+
+    public void setFailureProperty(String failureProperty)
+    {
+        testRunConfiguration.setFailureProperty(failureProperty);
+    }
+    
+    public void addSource(FileSet fileset)
+    {
+        fileset.setProject(project);
+        compilationConfiguration.addSource(fileset);
+    }
+    
+    public void addTestSource(FileSet fileset)
+    {
+        fileset.setProject(project);
+        compilationConfiguration.addTestSource(fileset);
+    }
+    
+    public void addLibrary(FileSet fileset)
+    {
+        fileset.setProject(project);
+        compilationConfiguration.addLibrary(fileset);
+    }
+    
+    public void setHeadless(boolean headless)
+    {
+        testRunConfiguration.setHeadless(headless);
+    }
+
+    public void setLocalTrusted(boolean isLocalTrusted)
+    {
+        testRunConfiguration.setLocalTrusted(isLocalTrusted);
+    }
+
+    public void setPlayer(String player)
+    {
+        this.player = player;
+    }
+
+    public void setPort(int port)
+    {
+        testRunConfiguration.setPort(port);
+    }
+
+    public void setReportDir(String reportDirPath)
+    {
+        this.reportDir = project.resolveFile(reportDirPath);
+    }
+
+    public void setServerBufferSize(int serverBufferSize)
+    {
+        testRunConfiguration.setServerBufferSize(serverBufferSize);
+    }
+
+    public void setSocketTimeout(int socketTimeout)
+    {
+        testRunConfiguration.setSocketTimeout(socketTimeout);
+    }
+
+    public void setSwf(String swf)
+    {
+        //match the swf URL to see if it's a remote location, if so, set the url instead of swf.
+        
+        File localFile = project.resolveFile(swf);
+        
+        if( localFile.exists() ) {
+            testRunConfiguration.setSwf(localFile);
+            LoggingUtil.log("Local path to SWF was given and SWF property will be used.");  
+        } else if( isValidURL( swf ) ) {
+            testRunConfiguration.setUrl(swf);
+            LoggingUtil.log("Remote path to SWF was given, setting URL property instead of SWF");
+        } else {
+            LoggingUtil.log("SWF and URL not set, file did not resolve to a local path or a remote path, please verify your format and try again.");
+        }
+        
+    }
+    
+    public void setSwf(File swf)
+    {
+        testRunConfiguration.setSwf(swf);
+    }
+    
+    public boolean isVerbose()
+    {
+        return verbose;
+    }
+
+    public void setVerbose(boolean verbose)
+    {
+        this.verbose = verbose;
+        LoggingUtil.VERBOSE = verbose;
+    }
+    
+    public void setWorkingDir(String workingDirPath)
+    {
+        this.workingDir = project.resolveFile(workingDirPath);
+    }
+    
+    public boolean shouldCompile()
+    {
+        File swf = testRunConfiguration.getSwf();
+        boolean noTestSources = !compilationConfiguration.getTestSources().provided();
+        return !noTestSources && (swf == null || !swf.exists());
+    }
+    
+    public void verify() throws BuildException
+    {
+        validateSharedProperties();
+        
+        if(shouldCompile())
+        {
+            compilationConfiguration.validate();
+        }
+        
+        testRunConfiguration.validate();
+        
+        propagateSharedConfiguration();
+    }
+
+    protected void validateSharedProperties() throws BuildException
+    {
+        LoggingUtil.log("Validating task attributes ...");
+        
+        if(!VALID_PLAYERS.contains(player))
+        {
+            throw new BuildException("The provided 'player' property value [" + player + "] must be either of the following values: " + VALID_PLAYERS.toString() + ".");
+        }
+        
+        File swf = testRunConfiguration.getSwf();
+        boolean noTestSources = !compilationConfiguration.getTestSources().provided();
+        String swfURL = testRunConfiguration.getUrl();
+        
+        //Check to make sure we have a valid swf, testsource or remote url before proceeding.
+        //Otherwise, notify the user to fix this before continuing.
+        if ((swf == null || !swf.exists()) && noTestSources && ( swfURL == null || swfURL.equals("") ) )
+        {
+            throw new BuildException("The provided 'swf' property value [" + (swf == null ? "" : swf.getPath()) + "] could not be found or is not a valid remote URL.");
+        }
+        
+        //Including a check for the swfURL
+        if( ( swf == null ) && (swfURL != null && swfURL != "") && testRunConfiguration.isLocalTrusted() ) 
+        {
+           throw new BuildException("The provided 'swf' property points to a remote location.  Please set localTrusted = false or change the location of your swf to a local path.");
+        }
+        
+        if(swf != null && !noTestSources)
+        {
+            throw new BuildException("Please specify the 'swf' property or use the 'testSource' element(s), but not both.");
+        }
+        
+        //if we can't find the ROYALE_HOME and we're using ADL or compilation
+        if((royaleHome == null || !royaleHome.exists()) && (new String("air").equals(testRunConfiguration.getPlayer()) || shouldCompile()))
+        {
+            throw new BuildException("Please specify, or verify the location for, the ROYALE_HOME property.  "
+                    + "It is required when testing with 'air' as the player or when using the 'testSource' element.  "
+                    + "It should point to the installation directory for an Apache Royale SDK.");
+        }
+    }
+    
+    protected void propagateSharedConfiguration()
+    {
+        LoggingUtil.log("Generating default values ...");
+        
+        //setup player
+        compilationConfiguration.setPlayer(player);
+        testRunConfiguration.setPlayer(player);
+        
+        //set ROYALE_HOME property to respective configs
+        compilationConfiguration.setRoyaleHome(royaleHome);
+        testRunConfiguration.setRoyaleHome(royaleHome);
+        
+        //create working directory if needed
+        if (workingDir == null || !workingDir.exists())
+        {
+            workingDir = project.resolveFile(DEFAULT_WORKING_PATH);
+            LoggingUtil.log("Using default working dir [" + workingDir.getAbsolutePath() + "]");
+        }
+
+        //create directory just to be sure it exists, already existing dirs will not be overwritten
+        workingDir.mkdirs();
+        
+        compilationConfiguration.setWorkingDir(workingDir);
+        
+        //create report directory if needed
+        if (reportDir == null || !reportDir.exists())
+        {
+            reportDir = project.resolveFile(DEFAULT_REPORT_PATH);
+            LoggingUtil.log("Using default reporting dir [" + reportDir.getAbsolutePath() + "]");
+        }
+
+        //create directory just to be sure it exists, already existing dirs will not be overwritten
+        reportDir.mkdir();
+        
+        testRunConfiguration.setReportDir(reportDir);
+    }
+    
+    public void setDebug(boolean value)
+    {
+        compilationConfiguration.setDebug(value);
+    }
+
+    public void setLoadConfig(LoadConfig loadconfig)
+    {
+        compilationConfiguration.setLoadConfig(loadconfig);
+    }
+
+}
\ No newline at end of file
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/configuration/TestRunConfiguration.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/configuration/TestRunConfiguration.java
new file mode 100644
index 0000000..ba88630
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/configuration/TestRunConfiguration.java
@@ -0,0 +1,274 @@
+/*
+ * 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.royale.test.ant.tasks.configuration;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.royale.test.ant.LoggingUtil;
+import org.apache.royale.test.ant.launcher.OperatingSystem;
+
+public class TestRunConfiguration implements StepConfiguration
+{
+    private final int FLOOR_FOR_PORT = 1;
+    private final int SHORTEST_SOCKET_TIMEOUT = 5000; //ms
+
+    private String player;
+    private File command = null;
+    private int display = 99;
+    private boolean failOnTestFailure = false;
+    private String failureProperty = "royaleunit.failed";
+    private File royaleHome = null;
+    private boolean headless = false;
+    private boolean isLocalTrusted = true;
+    private int port = 1024;
+    private File reportDir = null;
+    private int serverBufferSize = 262144; //bytes
+    private int socketTimeout = 60000; //milliseconds
+    private File swf = null;
+    private String url = null;
+    private File precompiledAppDescriptor = null;
+    private OperatingSystem os = OperatingSystem.identify();
+    
+    public File getCommand()
+    {
+        return command;
+    }
+
+    public void setCommand(File command)
+    {
+        this.command = command;
+    }
+    
+    public boolean isCustomCommand()
+    {
+        return command != null;
+    }
+
+    public int getDisplay()
+    {
+        return display;
+    }
+
+    public void setDisplay(int display)
+    {
+        this.display = display;
+    }
+
+    public boolean isFailOnTestFailure()
+    {
+        return failOnTestFailure;
+    }
+
+    public void setFailOnTestFailure(boolean failOnTestFailure)
+    {
+        this.failOnTestFailure = failOnTestFailure;
+    }
+
+    public String getFailureProperty()
+    {
+        return failureProperty;
+    }
+
+    public void setFailureProperty(String failureProperty)
+    {
+        this.failureProperty = failureProperty;
+    }
+    
+    public File getRoyaleHome()
+    {
+        return royaleHome;
+    }
+    
+    public void setRoyaleHome(File royaleHome)
+    {
+        this.royaleHome = royaleHome;
+    }
+    
+    public boolean isHeadless()
+    {
+        return headless;
+    }
+
+    public void setHeadless(boolean headless)
+    {
+        this.headless = headless;
+    }
+
+    public boolean isLocalTrusted()
+    {
+        return isLocalTrusted;
+    }
+    
+    public boolean usePolicyFile()
+    {
+        return !isLocalTrusted && player.equals("flash");
+    }
+
+    public void setLocalTrusted(boolean isLocalTrusted)
+    {
+        this.isLocalTrusted = isLocalTrusted;
+    }
+
+    public String getPlayer()
+    {
+        return player;
+    }
+
+    public void setPlayer(String player)
+    {
+        this.player = player;
+    }
+
+    public int getPort()
+    {
+        return port;
+    }
+
+    public void setPort(int port)
+    {
+        this.port = port;
+    }
+
+    public File getReportDir()
+    {
+        return reportDir;
+    }
+
+    public void setReportDir(File reportDir)
+    {
+        this.reportDir = reportDir;
+    }
+
+    public int getServerBufferSize()
+    {
+        return serverBufferSize;
+    }
+
+    public void setServerBufferSize(int serverBufferSize)
+    {
+        this.serverBufferSize = serverBufferSize;
+    }
+
+    public int getSocketTimeout()
+    {
+        return socketTimeout;
+    }
+
+    public void setSocketTimeout(int socketTimeout)
+    {
+        this.socketTimeout = socketTimeout;
+    }
+
+    public File getSwf()
+    {
+        return swf;
+    }
+    
+    public void setSwf(File swf)
+    {
+        this.swf = swf;
+    }
+    
+    public String getUrl() 
+    {
+        return url;
+    }
+
+    public void setUrl(String url) 
+    {
+        this.url = url;
+    }
+
+    public File getPrecompiledAppDescriptor() 
+    {
+        return precompiledAppDescriptor;
+    }
+
+    public void setPrecompiledAppDescriptor(File precompiledAppDescriptor) 
+    {
+        this.precompiledAppDescriptor = precompiledAppDescriptor;
+    }
+
+    public OperatingSystem getOs()
+    {
+        return os;
+    }
+
+    public void validate() throws BuildException
+    {
+        if(port < FLOOR_FOR_PORT)
+        {
+            throw new BuildException("The provided 'port' property value [" + port + "] must be great than " + FLOOR_FOR_PORT + ".");
+        }
+        
+        if(socketTimeout < SHORTEST_SOCKET_TIMEOUT)
+        {
+            throw new BuildException("The provided 'timeout' property value [" + socketTimeout + "] must be great than " + SHORTEST_SOCKET_TIMEOUT + ".");
+        }
+        
+        if(reportDir != null && !reportDir.exists())
+        {
+            LoggingUtil.log("Provided report directory path [" + reportDir.getPath() + "] does not exist.");
+        }
+        
+        if(command != null && !command.exists())
+        {
+            throw new BuildException("The provided command path [" + command + "] does not exist.");
+        }
+        
+        if(headless)
+        {
+            if(OperatingSystem.identify() != OperatingSystem.LINUX)
+            {
+                throw new BuildException("Headless mode can only be used on Linux with vncserver installed.");
+            }
+            
+            if(display < 1)
+            {
+                throw new BuildException("The provided 'display' number must be set higher than 0.  99 or higher is recommended.");
+            }
+        }
+    }
+    
+    public void log()
+    {
+        LoggingUtil.log("Using the following settings for the test run:");
+        
+        //ROYALE_HOME not required to run if not using ADL
+        if(royaleHome != null)
+        {
+            LoggingUtil.log("\tROYALE_HOME: [" + royaleHome.getAbsolutePath() + "]");         
+        }
+        
+        LoggingUtil.log("\thaltonfailure: [" + failOnTestFailure + "]");
+        LoggingUtil.log("\theadless: [" + headless + "]");
+        LoggingUtil.log("\tdisplay: [" + display + "]");
+        LoggingUtil.log("\tlocalTrusted: [" + isLocalTrusted + "]");
+        LoggingUtil.log("\tplayer: [" + player + "]");
+        
+        if(isCustomCommand())
+        {
+            LoggingUtil.log("\tcommand: [" + command + "]");
+        }
+        
+        LoggingUtil.log("\tport: [" + port + "]");
+        LoggingUtil.log("\tswf: [" + swf + "]");
+        LoggingUtil.log("\ttimeout: [" + socketTimeout + "ms]");
+        LoggingUtil.log("\ttoDir: [" + reportDir.getAbsolutePath() + "]");
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/types/CompilationFileSetCollection.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/types/CompilationFileSetCollection.java
new file mode 100644
index 0000000..bcfd5e7
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/types/CompilationFileSetCollection.java
@@ -0,0 +1,77 @@
+/*
+ * 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.royale.test.ant.tasks.types;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.types.FileSet;
+
+public class CompilationFileSetCollection
+{
+    protected List<FileSet> filesets;
+    
+    public CompilationFileSetCollection()
+    {
+        filesets = new ArrayList<FileSet>();
+    }
+    
+    public void add(FileSet fileset)
+    {
+        filesets.add(fileset);
+    }
+    
+    public boolean provided()
+    {
+        return filesets.size() != 0;
+    }
+    
+    public boolean isEmpty()
+    {
+        if(filesets.isEmpty())
+        {
+            return true;
+        }
+        
+        int includeCount = 0;
+        
+        for(FileSet fileset : filesets)
+        {
+            if(fileset.getDir().exists())
+            {
+                DirectoryScanner scanner = fileset.getDirectoryScanner();
+                includeCount += scanner.getIncludedFilesCount();
+            }
+        }
+        
+        return includeCount == 0;
+    }
+    
+    public boolean exists()
+    {
+        for(FileSet fileset : filesets)
+        {
+            if(!fileset.getDir().exists())
+            {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/types/LibraryPaths.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/types/LibraryPaths.java
new file mode 100644
index 0000000..ae347ea
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/types/LibraryPaths.java
@@ -0,0 +1,57 @@
+/*
+ * 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.royale.test.ant.tasks.types;
+
+import java.io.File;
+
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.types.FileSet;
+
+public class LibraryPaths extends CompilationFileSetCollection
+{
+    public LibraryPaths()
+    {
+        super();
+    }
+    
+    @Override
+    public void add(FileSet fileset)
+    {
+        super.add(fileset);
+    }
+    
+    public String getPathElements(String delimiter)
+    {
+        StringBuilder elements = new StringBuilder();
+        
+        for(FileSet fileset : filesets)
+        {
+            DirectoryScanner ds = fileset.getDirectoryScanner();
+            String[] files = ds.getIncludedFiles();
+            for(int i=0; i<files.length; i++)
+            {
+                if(files[i].endsWith(".swc"))
+                {
+                    elements.append("\"" + fileset.getDir().getAbsolutePath() + File.separator + files[i] + "\"");
+                    elements.append(delimiter);
+                }
+            }
+        }
+        
+        return elements.length() <= delimiter.length() ? "" : elements.substring(0, elements.length() - delimiter.length());
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/types/LoadConfig.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/types/LoadConfig.java
new file mode 100644
index 0000000..c460523
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/types/LoadConfig.java
@@ -0,0 +1,60 @@
+/*
+ * 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.royale.test.ant.tasks.types;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DynamicAttribute;
+
+public class LoadConfig implements DynamicAttribute
+{
+ 	public void setDynamicAttribute(String arg0, String arg1)
+			throws BuildException {
+		if("filename".equals(arg0))
+		{
+          filename = arg1;
+		}
+        else
+        {	
+          throw new BuildException("filename is only allowed attribute for <load-config>");
+        }
+	}
+
+    public String getFilename()
+    {
+        return filename;
+    }
+
+    public String getCommandLineArgument()
+    {
+        String argument = "";
+        if(filename == null || "".equals(filename))
+        {
+        	argument = "";
+        }
+        else
+        {
+        	
+        	argument = "-load-config+=\"" + filename + "\"";
+
+        }
+        
+        return argument;
+    }
+
+    private String filename;
+
+}
diff --git a/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/types/SourcePaths.java b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/types/SourcePaths.java
new file mode 100644
index 0000000..a0d0d40
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/java/org/apache/royale/test/ant/tasks/types/SourcePaths.java
@@ -0,0 +1,111 @@
+/*
+ * 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.royale.test.ant.tasks.types;
+
+import java.io.File;
+
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.types.FileSet;
+
+public class SourcePaths extends CompilationFileSetCollection
+{
+    public SourcePaths()
+    {
+        super();
+    }
+    
+    @Override
+    public void add(FileSet fileset)
+    {
+        super.add(fileset);
+    }
+    
+    public String getPathElements(String delimiter)
+    {
+        StringBuilder elements = new StringBuilder();
+        
+        for(FileSet fileset : filesets)
+        {
+            elements.append("\"" + fileset.getDir().getAbsolutePath() + "\"");
+            elements.append(delimiter);
+        }
+        
+        return elements.length() <= delimiter.length() ? "" : elements.substring(0, elements.length() - delimiter.length());
+    }
+    
+    public String getImports()
+    {
+        StringBuilder elements = new StringBuilder();
+        
+        for(FileSet fileset : filesets)
+        {
+            DirectoryScanner ds = fileset.getDirectoryScanner();
+            for(String file : ds.getIncludedFiles())
+            {
+                if(file.endsWith(".as") || file.endsWith(".mxml"))
+                {
+                    String pathWithOutSuffix = file.substring(0, file.lastIndexOf('.'));
+                    String canonicalClassName = pathWithOutSuffix.replace(File.separatorChar, '.');
+                    elements.append("import ");
+                    elements.append(canonicalClassName);
+                    elements.append(";\n");
+                }
+            }
+        }
+        
+        return elements.toString();
+    }
+    
+    public String getClasses()
+    {
+        StringBuilder elements = new StringBuilder();
+        
+        for(FileSet fileset : filesets)
+        {
+            DirectoryScanner ds = fileset.getDirectoryScanner();
+            for(String file : ds.getIncludedFiles())
+            {
+                String pathWithOutSuffix = file.substring(0, file.lastIndexOf('.'));
+                String canonicalClassName = pathWithOutSuffix.replace(File.separatorChar, '.');
+                String className = canonicalClassName.substring(canonicalClassName.lastIndexOf('.') + 1, canonicalClassName.length());
+                elements.append(className);
+                elements.append(',');
+            }
+        }
+        
+        return elements.length() == 0 ? "" : elements.substring(0, elements.length() - 1);
+    }
+    
+    public String getCanonicalClasses(String delimiter)
+    {
+        StringBuilder elements = new StringBuilder();
+        
+        for(FileSet fileset : filesets)
+        {
+            DirectoryScanner ds = fileset.getDirectoryScanner();
+            for(String file : ds.getIncludedFiles())
+            {
+                String pathWithOutSuffix = file.substring(0, file.lastIndexOf('.'));
+                String canonicalClassName = pathWithOutSuffix.replace(File.separatorChar, '.');
+                elements.append(canonicalClassName);
+                elements.append(delimiter);
+            }
+        }
+        
+        return elements.length() <= delimiter.length() ? "" : elements.substring(0, elements.length() - delimiter.length());
+    }
+}
diff --git a/royaleunit-ant-tasks/src/main/resources/TestRunner.template b/royaleunit-ant-tasks/src/main/resources/TestRunner.template
new file mode 100644
index 0000000..b4a4359
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/resources/TestRunner.template
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+-->
+<@APPLICATION_PREFIX@:@APPLICATION_CLASS@ 
+@NAMESPACES@ 
+creationComplete="runTests();">
+    
+    <@MXML_PREFIX@:Script>
+        <![CDATA[
+            import org.apache.royale.test.listeners.@CI_LISTENER_CLASS@;
+            import org.apache.royale.test.RoyaleUnitCore;
+            
+@IMPORT_REFS@
+            
+            public function runTests() : void {
+                var core : RoyaleUnitCore = new RoyaleUnitCore();
+                core.addListener(new @CI_LISTENER_CLASS@());
+                core.runClasses(
+[@CLASS_REFS@]
+                );
+            }
+        ]]>
+    </@MXML_PREFIX@:Script>
+</@APPLICATION_PREFIX@:@APPLICATION_CLASS@>
diff --git a/royaleunit-ant-tasks/src/main/resources/downloads.xml b/royaleunit-ant-tasks/src/main/resources/downloads.xml
new file mode 100644
index 0000000..73e8451
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/resources/downloads.xml
@@ -0,0 +1,396 @@
+<?xml version="1.0"?>
+<!--
+
+  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.
+
+-->
+<project name="downloads" default="main" basedir=".">
+    <echo>basedir is ${basedir}</echo>
+    <echo>ROYALE_COMPILER_HOME is ${ROYALE_COMPILER_HOME}</echo>
+    
+  <!--
+      Notes:
+          For Apache, the JARS must be removed from the repository.
+
+          Licenses:
+              dom4j (1.6.1) - BSD
+              Java-WebSocket (1.4.0) - MIT
+              slf4j-api (1.7.25) - MIT
+  -->
+
+  <!-- this script supports the usingDownloadCache property and
+       downloadCacheFolder property to cache downloads in the
+       folder specified by downloadCacheFolder.  This can make
+       a huge difference in future runs although there is some
+       risk around caching bad downloads and/or needing to
+       clean up the cache -->
+
+  <property name="ROYALE_COMPILER_HOME" location="${basedir}/../../../../compiler-jx"/>
+  <echo>ROYALE_COMPILER_HOME is ${ROYALE_COMPILER_HOME}</echo>
+
+  <property name="lib.dir" value="${ROYALE_COMPILER_HOME}/lib"/>
+  <property name="download.dir" value="${ROYALE_COMPILER_HOME}/in"/>
+
+  <property file="${ROYALE_COMPILER_HOME}/local.properties"/>
+
+  <property name="maven.search.url" value="https://repo1.maven.org/maven2"/>
+
+  <property file="${ROYALE_COMPILER_HOME}/env.properties"/>
+  <property environment="env"/>
+  <property file="${ROYALE_COMPILER_HOME}/local.properties"/>
+  <property file="${ROYALE_COMPILER_HOME}/build.properties"/>
+
+
+  <!--
+      Because the downloads requires a network connection and the JARs don't change very often,
+      they are each downloaded only if they don't already exist. 
+  -->
+  <target name="main" depends="prepare, all" description="Downloads all the required thirdparty JARs"/>
+  
+  <target name="prepare">
+    <echo message="Making lib directory ${lib.dir}"/>
+    <mkdir dir="${lib.dir}"/>
+  </target>
+
+  <!--
+      Downloads
+  -->
+
+  <target name="all" description="Downloads and copies all dependencies to the lib directory.">
+
+    <!--  dom4j -->
+    <property name="dom4j.name" value="dom4j"/>
+    <property name="dom4j.version" value="1.6.1"/>
+    <antcall target="download-dependency">
+      <param name="name" value="${dom4j.name}"/>
+      <param name="src.server" value="${maven.search.url}"/>
+      <param name="src.folder" value="dom4j/dom4j/${dom4j.version}"/>
+      <param name="src.filename" value="dom4j-${dom4j.version}.jar"/>
+      <param name="src.checksum" value="4d8f51d3fe3900efc6e395be48030d6d"/>
+      <param name="dest.folder" value=""/>
+      <param name="dest.filename" value="${dom4j.name}.jar"/>
+      <param name="license.use.url" value="https://raw.githubusercontent.com/dom4j/dom4j/master/LICENSE"/>
+      <param name="license.cacheName" value="dom4j-LICENSE.txt"/>
+    </antcall>
+
+    <!--  Java-WebSocket -->
+    <property name="javawebsocket.name" value="java-websocket"/>
+    <property name="javawebsocket.version" value="1.4.0"/>
+    <antcall target="download-dependency">
+      <param name="name" value="${javawebsocket.name}"/>
+      <param name="src.server" value="${maven.search.url}"/>
+      <param name="src.folder" value="org/java-websocket/Java-WebSocket/${javawebsocket.version}"/>
+      <param name="src.filename" value="Java-WebSocket-${javawebsocket.version}.jar"/>
+      <param name="src.checksum" value="59c1134b8c50ace9e074e9f1d5da4aaa"/>
+      <param name="dest.folder" value=""/>
+      <param name="dest.filename" value="${javawebsocket.name}.jar"/>
+      <param name="license.use.url" value="https://raw.githubusercontent.com/TooTallNate/Java-WebSocket/master/LICENSE"/>
+      <param name="license.cacheName" value="${javawebsocket.name}-LICENSE.txt"/>
+    </antcall>
+
+    <!--  slf4j-api -->
+    <property name="slf4j.name" value="slf4j-api"/>
+    <property name="slf4j.version" value="1.7.25"/>
+    <antcall target="download-dependency">
+      <param name="name" value="${slf4j.name}"/>
+      <param name="src.server" value="${maven.search.url}"/>
+      <param name="src.folder" value="org/slf4j/slf4j-api/${slf4j.version}"/>
+      <param name="src.filename" value="slf4j-api-${slf4j.version}.jar"/>
+      <param name="src.checksum" value="caafe376afb7086dcbee79f780394ca3"/>
+      <param name="dest.folder" value=""/>
+      <param name="dest.filename" value="${slf4j.name}.jar"/>
+      <param name="license.use.url" value="https://raw.githubusercontent.com/qos-ch/slf4j/master/LICENSE.txt"/>
+      <param name="license.cacheName" value="${slf4j.name}-LICENSE.txt"/>
+    </antcall>
+  </target>
+
+
+
+  <!--
+      Utilities
+  -->
+
+  <target name="check-dependency" description="Checks if project jar is in lib directory.">
+    <echo>checking for ${lib.dir}/${dest.folder}/${name}.jar</echo>
+    <available file="${lib.dir}/${dest.folder}/${name}.jar" property="project.jar.exists"/>
+  </target>
+
+  <target name="echo-project-jar">
+    <echo file="${basedir}/project.properties">project.echo=${INFO_DOWNLOADING_FILE_FROM}</echo>
+    <replace file="${basedir}/project.properties" token="{0}" value="${srcPath}"/>
+    <replace file="${basedir}/project.properties" token="{1}" value="${srcDomain}"/>
+    <property file="${basedir}/project.properties"/>
+    <delete file="${basedir}/project.properties"/>
+    <echo>${project.echo}</echo>
+  </target>
+  
+  <target name="download-dependency" depends="check-dependency" unless="project.jar.exists" description="Downloads a jar + license to the lib directory.">
+    <antcall target="echo-project-jar">
+      <param name="srcDomain" value="${src.server}"/>
+      <param name="srcPath" value="${src.folder}/${src.filename}"/>
+    </antcall>
+    <mkdir dir="${lib.dir}/${dest.folder}"/>
+
+    <antcall target="download-apache-license" />
+    <antcall target="download-other-license" />
+
+    <!-- ant_on_air in Installer 3.1 doesn't support 'or' yet -->
+    <condition property="project.download.jar">
+      <and>
+          <not>
+              <contains string="${src.filename}" substring=".tar" />
+          </not>
+          <not>
+              <contains string="${src.filename}" substring=".zip" />
+          </not>
+      </and>
+    </condition>
+    
+    <antcall target="download-dependency-jar">
+      <param name="server" value="${src.server}"/>
+      <param name="folder" value="${src.folder}"/>
+      <param name="srcFileName" value="${src.filename}"/>
+      <param name="destDir" value="${lib.dir}/${dest.folder}"/>
+      <param name="destFile" value="${dest.filename}"/>
+      <param name="checksum" value="${src.checksum}"/>
+    </antcall>
+
+    <antcall target="download-dependency-zip">
+      <param name="server" value="${src.server}"/>
+      <param name="folder" value="${src.folder}"/>
+      <param name="srcFileName" value="${src.filename}"/>
+      <param name="srcJarPath" value="${src.jarPath}"/>
+      <param name="destDir" value="${lib.dir}/${dest.folder}"/>
+      <param name="destFile" value="${dest.filename}"/>
+      <param name="checksum" value="${src.checksum}"/>
+    </antcall>
+  </target>
+
+  <target name="download-apache-license" if="license.use.apache" description="Downloads the Apache license to the lib directory.">
+    <get src="http://www.apache.org/licenses/LICENSE-2.0" dest="${lib.dir}/${dest.folder}/${name}-LICENSE.html" ignoreerrors="true"/>
+    <antcall target="get-from-cache-if-needed" >
+        <param name="srcFile" value="LICENSE-2.0.html" />
+        <param name="destFile" value="${name}-LICENSE.html" />
+        <param name="destDir" value="${lib.dir}/${dest.folder}" />
+    </antcall>
+    <antcall target="fail-if-not-found" >
+        <param name="destFile" value="${name}-LICENSE.html" />
+        <param name="destDir" value="${lib.dir}/${dest.folder}" />
+    </antcall>
+  </target>
+  
+  <target name="download-other-license" if="license.use.url" description="Downloads a non-Apache license to the lib directory.">
+    <get src="${license.use.url}" dest="${lib.dir}/${dest.folder}/${name}-LICENSE.txt" ignoreerrors="true"/>
+    <antcall target="get-from-cache-if-needed" >
+        <param name="srcFile" value="${license.cacheName}" />
+        <param name="destFile" value="${name}-LICENSE.txt" />
+        <param name="destDir" value="${lib.dir}/${dest.folder}" />
+    </antcall>
+    <antcall target="fail-if-not-found" >
+        <param name="destFile" value="${name}-LICENSE.txt" />
+        <param name="destDir" value="${lib.dir}/${dest.folder}" />
+    </antcall>
+  </target>
+  
+  <target name="download-dependency-jar" if="project.download.jar" description="Downloads a jar to the lib directory.">
+    <antcall target="download-jar">
+      <param name="srcDomain" value="${server}"/>
+      <param name="srcFolder" value="${folder}"/>
+      <param name="cacheFolder" value="${folder}"/>
+      <param name="srcFile" value="${srcFileName}"/>
+      <param name="md5" value="${checksum}"/>
+    </antcall>
+  </target>
+
+  <target name="download-dependency-zip" unless="project.download.jar" description="Downloads a zip to the lib directory.">
+    <antcall target="download-zip">
+      <param name="srcDomain" value="${server}"/>
+      <param name="srcFolder" value="${folder}"/>
+      <param name="srcFile" value="${srcFileName}"/>
+      <param name="srcJarPath" value="${srcJarPath}"/>
+      <param name="md5" value="${checksum}"/>
+    </antcall>
+  </target>
+    
+  <!--
+      Download a zip or gz file, extracts the jar file, and optionally copies the jar
+      file to a different location and optinally verifies the checksum and optionally
+      caches the file, and optionally pulls the file from the cache instead of downloading.  
+      If the checksum fails, this script fails.
+
+      Params are:
+          srcDomain - the domain
+          srcFolder - path to file
+          srcFile - a .gz file for untar with gzip, else unzip
+          [md5]
+          [srcJarPath] - both src and dest required for the copy
+          [destJarFile]
+
+      Note: This is purposely coded without <if><else><then> so that a dependency on
+      ant-contrib.jar isn't required.        
+  -->
+  <target name="download-zip" depends="check-cache" description="Downloads tar/zip, and optionally verifies checksum and copies extracted jar.">
+    <mkdir dir="${download.dir}"/>
+    <antcall target="get-if-not-cached">
+      <param name="destDir" value="${download.dir}"/>
+      <param name="destFile" value="${srcFile}"/>
+      <param name="message" value="Checksum mismatch for ${download.dir}/${srcFile}"/>
+    </antcall>
+    <antcall target="copy-if-cached">
+      <param name="destDir" value="${download.dir}"/>
+      <param name="destFile" value="${srcFile}"/>
+    </antcall>
+    <condition property="zip.compressed">
+      <matches string="${srcFile}" pattern="^*.zip$"/>
+    </condition>
+    <antcall target="untar-file"/>
+    <antcall target="unzip-file"/>
+    <condition property="destination.known">
+      <and>
+        <isset property="srcJarPath"/>
+        <isset property="destDir"/>
+        <isset property="destFile"/>
+      </and>
+    </condition>
+    <antcall target="copy-downloaded-jar"/>
+  </target>
+
+  <target name="download-bz2" depends="check-cache" description="Downloads bz2, and optionally verifies checksum and copies extracted jar.">
+    <mkdir dir="${download.dir}"/>
+    <antcall target="get-if-not-cached">
+      <param name="dest" value="${download.dir}/${srcFile}"/>
+      <param name="message" value="Checksum mismatch for ${download.dir}/${srcFile}"/>
+    </antcall>
+    <antcall target="copy-if-cached">
+      <param name="dest" value="${download.dir}/${srcFile}"/>
+    </antcall>
+    <untar src="${download.dir}/${srcFile}" dest="${download.dir}/temp" compression="bzip2"/>
+    <condition property="destination.known">
+      <and>
+        <isset property="srcJarPath"/>
+        <isset property="destJarFile"/>
+      </and>
+    </condition>
+    <antcall target="copy-downloaded-jar"/>
+  </target>
+
+  <!--
+      Download a jar file and optionally verify the checksum.
+      If the checksum fails, this script fails.
+        
+      Params are:
+          srcDomain
+          srcFolder
+          srcFile
+          destJarFile
+          [md5]
+  -->
+  <target name="download-jar" depends="check-cache" description="Downloads jar, and optionally verifies checksum.">
+    <antcall target="get-if-not-cached">
+      <param name="message" value="Checksum mismatch for ${destJarFile}"/>
+    </antcall>
+    <antcall target="copy-if-cached" />
+  </target>
+
+  <target name="untar-file" unless="zip.compressed" description="Untars zipFile">
+    <untar src="${download.dir}/${srcFile}" dest="${download.dir}/temp" compression="gzip"/>
+  </target>
+
+  <target name="unzip-file" if="zip.compressed" description="Unzips zipFile">
+    <unzip src="${download.dir}/${srcFile}" dest="${download.dir}/temp"/>
+  </target>
+
+  <target name="get-if-not-cached" unless="found-in-cache">
+    <get src="${srcDomain}/${srcFolder}/${srcFile}" dest="${destDir}/${destFile}" ignoreerrors="true"/>
+    <!-- this is a different cache for the CI servers.  It tries the network first, then the cache if failure -->
+    <antcall target="get-from-cache-if-needed" />
+    <antcall target="fail-if-not-found" />
+    <antcall target="check-sum">
+      <param name="message" value="Checksum mismatch for ${destDir}/${destFile}"/>
+    </antcall>
+    <antcall target="put-in-cache"/>
+  </target>
+
+  <target name="copy-if-cached" if="found-in-cache">
+    <!-- this string comes from the Royale en_US.properties because for now, this
+         target won't get called unless this script is called from the Royale install -->
+    <echo>${INFO_USING_CACHED_FILE} ${downloadCacheFolder}/${srcFolder}/${srcFile}</echo>
+    <copy file="${downloadCacheFolder}/${srcFolder}/${srcFile}" tofile="${destDir}/${destFile}" overwrite="true"/>
+  </target>
+
+  <target name="check-cache" if="usingDownloadCache">
+      <echo>${downloadCacheFolder} ${srcFolder} ${srcFile}</echo>
+    <available file="${downloadCacheFolder}/${srcFolder}/${srcFile}" property="found-in-cache"/>
+  </target>
+
+  <target name="put-in-cache" if="usingDownloadCache">
+    <copy tofile="${downloadCacheFolder}/${srcFolder}/${srcFile}" file="${destDir}/${destFile}"/>
+  </target>
+
+  <target name="check-sum" if="md5" description="Verifies MD5 checksum, and fails if checksum doesn't match">
+    <checksum file="${destDir}/${destFile}" algorithm="MD5" verifyproperty="we.failed" property="${md5}"/>
+    <fail message="${message}">
+      <condition>
+        <equals arg1="${we.failed}" arg2="false"/>
+      </condition>
+    </fail>
+  </target>
+
+  <target name="copy-downloaded-jar" if="destination.known">
+    <mkdir dir="${lib.dir}"/>
+    <copy file="${download.dir}/temp/${srcJarPath}" toFile="${destDir}/${destFile}" verbose="true"/>
+  </target>
+
+  <target name="fail-with-message" if="we.failed" description="Conditionally fails with the specified message">
+    <fail message="${message}"/>
+  </target>
+
+    <target name="fail-if-not-found">
+        <fail message="${destDir}/${destFile} could not be downloaded or found in cache">
+            <condition>
+                <not>
+                    <available file="${destDir}/${destFile}" />
+                </not>
+            </condition>
+        </fail>
+    </target>
+
+    <target name="double-check-file" >
+        <echo>${env.ROYALE_DOWNLOAD_CACHE}</echo>
+        <condition property="still-no-file" value="true">
+            <and>
+                <not>
+                    <available file="${destDir}/${destFile}" />
+                </not>
+                <isset property="env.ROYALE_DOWNLOAD_CACHE" />
+            </and>
+        </condition>
+        <echo>Need file: ${still_no_file}</echo>
+    </target>
+    <target name="get-from-cache-if-needed" depends="double-check-file" if="still-no-file">
+        <copy file="${env.ROYALE_DOWNLOAD_CACHE}/${srcFile}" tofile="${destDir}/${destFile}" />
+    </target>
+
+
+  <!--
+      Cleanup
+  -->
+  <target name="clean" description="Removes thirdparty downloads.">
+    <delete failonerror="false" includeEmptyDirs="true">
+      <fileset dir="${download.dir}"/>
+    </delete>
+  </target>
+</project>
diff --git a/royaleunit-ant-tasks/src/main/resources/royaleUnitDescriptor.template b/royaleunit-ant-tasks/src/main/resources/royaleUnitDescriptor.template
new file mode 100644
index 0000000..e2e0207
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/resources/royaleUnitDescriptor.template
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--
+  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.
+-->
+<application xmlns="http://ns.adobe.com/air/application/@ADT_VERSION@">
+	<id>RoyaleUnitAdlWrapper</id>
+	<filename>RoyaleUnitAdlWrapper</filename>
+	<name>RoyaleUnit Adl Wrapper</name>
+	<@VERSION_PROP@>1.0.0</@VERSION_PROP@>
+	<description>Wrapper application for use with the RoyaleUnit Ant task.</description>
+	<initialWindow>
+		<title>RoyaleUnit Adl Wrapper</title>
+		<content>@ADL_SWF@</content>
+		<visible>true</visible> 
+        <minimizable>true</minimizable> 
+        <maximizable>false</maximizable> 
+        <resizable>false</resizable> 
+        <width>320</width> 
+        <height>240</height> 
+	</initialWindow>
+</application>
diff --git a/royaleunit-ant-tasks/src/main/resources/royaleUnitTasks.tasks b/royaleunit-ant-tasks/src/main/resources/royaleUnitTasks.tasks
new file mode 100644
index 0000000..4969030
--- /dev/null
+++ b/royaleunit-ant-tasks/src/main/resources/royaleUnitTasks.tasks
@@ -0,0 +1,16 @@
+# 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.
+
+royaleunit=org.apache.royale.test.ant.tasks.RoyaleUnitTask
diff --git a/settings-template.xml b/settings-template.xml
index 07b2c2d..bc78230 100644
--- a/settings-template.xml
+++ b/settings-template.xml
@@ -42,7 +42,7 @@
             <repositories>
                 <repository>
                     <id>apache-snapshots</id>
-                    <url>http://repository.apache.org/snapshots/</url>
+                    <url>https://repository.apache.org/snapshots/</url>
                     <releases>
                         <enabled>false</enabled>
                     </releases>
@@ -54,7 +54,7 @@
             <pluginRepositories>
                 <pluginRepository>
                     <id>apache-snapshots</id>
-                    <url>http://repository.apache.org/snapshots/</url>
+                    <url>https://repository.apache.org/snapshots/</url>
                     <releases>
                         <enabled>false</enabled>
                     </releases>
diff --git a/swfutils/pom.xml b/swfutils/pom.xml
index bebc918..4d0d890 100644
--- a/swfutils/pom.xml
+++ b/swfutils/pom.xml
@@ -1,35 +1,45 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.apache.royale.compiler</groupId>
-    <artifactId>royale-compiler-parent</artifactId>
-    <version>0.9.4</version>
-  </parent>
-
-  <artifactId>swfutils</artifactId>
-  <version>0.9.4</version>
-
-  <name>Apache Royale: Compiler: SWFUtils</name>
-  <description>The Apache Royale Compiler SWF Utility classes</description>
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+

+  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.

+

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+  <modelVersion>4.0.0</modelVersion>

+

+  <parent>

+    <groupId>org.apache.royale.compiler</groupId>

+    <artifactId>royale-compiler-parent</artifactId>

+    <version>0.9.6</version>

+  </parent>

+

+  <artifactId>swfutils</artifactId>

+  <version>0.9.6</version>

+

+  <name>Apache Royale: Compiler: SWFUtils</name>

+  <description>The Apache Royale Compiler SWF Utility classes</description>

+

+  <build>

+    <plugins>

+        <plugin>

+            <groupId>io.github.zlika</groupId>

+            <artifactId>reproducible-build-maven-plugin</artifactId>

+            <version>0.9</version>

+        </plugin>

+    </plugins>

+  </build>

+

+</project>